简体   繁体   English

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

[英]Get window state of another process

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 Maximized or Minimized ,it ever returns Normal . 但如果进程MaximizedMinimized ,它将返回Normal

How to fix this? 如何解决这个问题?

You'll need to use Win32 through P/Invoke for checking the state of another window. 您需要通过P / Invoke使用Win32来检查另一个窗口的状态。 Here is some sample code: 以下是一些示例代码:

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提供。

You're using proc.StartInfo, which is incorrect. 你正在使用proc.StartInfo,这是不正确的。 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. 它只是您可以设置的启动信息,然后可以在启动时传递给进程。

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. 感谢Kakashi指出我们在测试结果时的错误。

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 enum的定义ShowWindowCommands和其他函数取自www.PInvoke.net

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM