C# 获取另一个进程的窗口状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11065026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 16:21:21  来源:igfitidea点击:

Get window state of another process

c#process

提问by Hyman

How do I get the window state(maximized, minimized) of another process that's running?

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

I'd tried by using this:

我试过使用这个:

Process[] procs = Process.GetProcesses();

        foreach (Process proc in procs)
        {

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

            }
        }

But if process is Maximizedor Minimized,it ever returns Normal.

但是如果 process 是Maximizedor Minimized,它永远返回Normal

How to fix this?

如何解决这个问题?

采纳答案by Douglas

You'll need to use Win32 through P/Invoke for checking the state of another window. Here is some sample code:

您需要通过 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,
}

Definition courtesy of pinvoke.net.

定义由 pinvoke.net 提供。

回答by Marcel N.

You're using proc.StartInfo, which is incorrect. It does not reflect the runtime window style of the target process. It is just startup info you can set and can then be passed on to the process when it starts up.

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

The C# signature is:

C# 签名是:

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

You need to use p/invoke and call GetWindowLong(hWnd, GWL_STYLE), and pass proc.MainWindowHandle as the hWnd parameter.

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

You can check if the window is minimized/maximized by doing something like:

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

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
}

NOTE:The values for the flags (WS_MINIMIZE, etc), can be found in this page: http://www.pinvoke.net/default.aspx/user32.getwindowlong

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

Thanks to Kakashi for pointing our the error in testing the result.

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

回答by Mic

Two Window States (maximized / minimized) can be gotten by calling WinAPI IsIconic() / IsZoomed() like this:

通过像这样调用 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);
    }

Definition of enum ShowWindowCommands and other functions were taken from www.PInvoke.net

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

回答by Ladislav

In Windows PowerShell you can do this by following code:

在 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)"
}