如何获取正在运行的另一个进程的窗口状态(maximized,minimized)?
我试过用这个:
Process[] procs = Process.GetProcesses();
foreach (Process proc in procs)
{
if (proc.ProcessName == "notepad")
{
MessageBox.Show(proc.StartInfo.WindowStyle.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
但如果过程是Maximized或者Minimized,它就会回归Normal.
如何解决这个问题?
Dou*_*las 24
您需要通过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,
}
Run Code Online (Sandbox Code Playgroud)
定义由pinvoke.net提供.
你正在使用proc.StartInfo,这是不正确的.它不反映目标进程的运行时窗口样式.它只是您可以设置的启动信息,然后可以在启动时传递给进程.
C#签名是:
[DllImport("user32.dll", SetLastError=true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
Run Code Online (Sandbox Code Playgroud)
您需要使用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
}
Run Code Online (Sandbox Code Playgroud)
注意:标志的值(WS_MINIMIZE等)可以在此页面中找到:http://www.pinvoke.net/default.aspx/user32.getwindowlong
感谢Kakashi指出我们在测试结果时的错误.
在 Windows PowerShell 中,您可以通过以下代码来执行此操作:
Add-Type -AssemblyName UIAutomationClient
$prList = Get-Process -Name "<ProcessNamesWhichHaveWindow>"
$prList | % {
try {
$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)"
}
catch { }
}
Run Code Online (Sandbox Code Playgroud)