13

如何获取另一个正在运行的进程的窗口状态( maximized, )?minimized

我试过用这个:

Process[] procs = Process.GetProcesses();

        foreach (Process proc in procs)
        {

            if (proc.ProcessName == "notepad")
            {
                MessageBox.Show(proc.StartInfo.WindowStyle.ToString());

            }
        }

但如果过程是MaximizedMinimized,它永远返回Normal

如何解决这个问题?

4

4 回答 4

27

您需要通过 P/Invoke 使用 Win32 来检查另一个窗口的状态。这是一些示例代码:

static void Main(string[] args)
{
    Process[] procs = Process.GetProcesses();

    foreach (Process proc in procs)
    {
        if (proc.ProcessName == "notepad")
        {
            var placement = GetPlacement(proc.MainWindowHandle);
            MessageBox.Show(placement.showCmd.ToString());
        }
    }
}

private static WINDOWPLACEMENT GetPlacement(IntPtr hwnd)
{
    WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
    placement.length = Marshal.SizeOf(placement);
    GetWindowPlacement(hwnd, ref placement);
    return placement;
}

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetWindowPlacement(
    IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

[Serializable]
[StructLayout(LayoutKind.Sequential)]
internal struct WINDOWPLACEMENT
{
    public int length;
    public int flags;
    public ShowWindowCommands showCmd;
    public System.Drawing.Point ptMinPosition;
    public System.Drawing.Point ptMaxPosition;
    public System.Drawing.Rectangle rcNormalPosition;
}

internal enum ShowWindowCommands : int
{
    Hide = 0,
    Normal = 1,
    Minimized = 2,
    Maximized = 3,
}

定义由 pinvoke.net 提供。

于 2012-06-16T16:23:30.103 回答
7

您正在使用 proc.StartInfo,这是不正确的。它不反映目标进程的运行时窗口样式。它只是您可以设置的启动信息,然后可以在启动时传递给进程。

C# 签名是:

[DllImport("user32.dll", SetLastError=true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);

您需要使用 p/invoke 并调用 GetWindowLong(hWnd, GWL_STYLE),并将 proc.MainWindowHandle 作为 hWnd 参数传递。

您可以通过执行以下操作来检查窗口是否最小化/最大化:

int style = GetWindowLong(proc.MainWindowHandle,  GWL_STYLE);
if((style & WS_MAXIMIZE) == WS_MAXIMIZE) 
{
   //It's maximized
} 
else if((style & WS_MINIMIZE) == WS_MINIMIZE) 
{
  //It's minimized
}

注意:标志的值(WS_MINIMIZE 等)可以在此页面中找到:http ://www.pinvoke.net/default.aspx/user32.getwindowlong

感谢卡卡西指出我们测试结果的错误。

于 2012-06-16T16:19:35.707 回答
5

在 Windows PowerShell 中,您可以通过以下代码执行此操作:

Add-Type -AssemblyName UIAutomationClient
$prList = Get-Process -Name "<ProcessNamesWhichHaveWindow>"
$prList | % {
    $ae = [System.Windows.Automation.AutomationElement]::FromHandle($_.MainWindowHandle)
    $wp = $ae.GetCurrentPattern([System.Windows.Automation.WindowPatternIdentifiers]::Pattern)
    echo "Window title: $($_.MainWindowTitle)"
    echo "Window visual state: $($wp.Current.WindowVisualState)"
}
于 2016-10-14T11:10:32.723 回答
3

通过调用 WinAPI IsIconic() / IsZoomed() 可以获得两个窗口状态(最大化/最小化),如下所示:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool IsIconic(IntPtr hWnd);

    [DllImport("user32.dll")]
    public static extern bool ShowWindowAsync(IntPtr hWnd, ShowWindowCommands cmdShow);

    if (IsIconic(_helpWindow.MainWindowHandle)) {
        ShowWindowAsync(_helpWindow.MainWindowHandle, ShowWindowCommands.SW_RESTORE);
    }

枚举 ShowWindowCommands 和其他函数的定义取自 www.PInvoke.net

于 2014-06-04T09:20:26.233 回答