检测外部进程是否是交互式的并且是否有任何可见的 UI
Detect if external process is interactive and has any visible UI
我似乎无法找到一种方法来确定 Process
是否具有用户界面,例如a window,哪个对用户可见?
Environment.UserInteractive
对外部进程没有用
process.MainWindowHandle != IntPtr.Zero
在我的测试中似乎总是 return 错误?
我想区分 say Notepad 和 conhost
- 从您的
Process
实例中找出进程 ID。
- 用
EnumWindows
枚举顶级windows。
- 调用
GetWindowThreadProcessId
,看是否匹配目标PID。
- 调用
IsWindowVisible
and/or IsIconic
来测试 window 是否对用户可见。
有关 System.Diagnostics.Process.MainWindowHandle
的 MSDN 文章指出以下内容
If you have just started a process and want to use its main window handle, consider using the WaitForInputIdle method to allow the process to finish starting, ensuring that the main window handle has been created. Otherwise, an exception will be thrown.
他们的意思是 Window
在您调用 MainWindowHandle
后可能需要几秒钟才能呈现,返回 IntPtr.Zero
即使您可以清楚地看到显示 Window
。
参考https://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx
跟随@David Heffernan,这就是我所做的:
HWND FindTopWindow(DWORD pid)
{
std::pair<HWND, DWORD> params = { 0, pid };
// Enumerate the windows using a lambda to process each window
BOOL bResult = EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL
{
auto pParams = (std::pair<HWND, DWORD>*)(lParam);
DWORD processId;
if (GetWindowThreadProcessId(hwnd, &processId) && processId == pParams->second)
{
if (IsWindowVisible(hwnd)) {
// Stop enumerating
SetLastError(-1);
pParams->first = hwnd;
return FALSE;
}
return TRUE;
}
// Continue enumerating
return TRUE;
}, (LPARAM)¶ms);
if (!bResult && GetLastError() == -1 && params.first)
{
return params.first;
}
return 0;
}
我似乎无法找到一种方法来确定 Process
是否具有用户界面,例如a window,哪个对用户可见?
Environment.UserInteractive
对外部进程没有用process.MainWindowHandle != IntPtr.Zero
在我的测试中似乎总是 return 错误?
我想区分 say Notepad 和 conhost
- 从您的
Process
实例中找出进程 ID。 - 用
EnumWindows
枚举顶级windows。 - 调用
GetWindowThreadProcessId
,看是否匹配目标PID。 - 调用
IsWindowVisible
and/orIsIconic
来测试 window 是否对用户可见。
有关 System.Diagnostics.Process.MainWindowHandle
的 MSDN 文章指出以下内容
If you have just started a process and want to use its main window handle, consider using the WaitForInputIdle method to allow the process to finish starting, ensuring that the main window handle has been created. Otherwise, an exception will be thrown.
他们的意思是 Window
在您调用 MainWindowHandle
后可能需要几秒钟才能呈现,返回 IntPtr.Zero
即使您可以清楚地看到显示 Window
。
参考https://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx
跟随@David Heffernan,这就是我所做的:
HWND FindTopWindow(DWORD pid)
{
std::pair<HWND, DWORD> params = { 0, pid };
// Enumerate the windows using a lambda to process each window
BOOL bResult = EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL
{
auto pParams = (std::pair<HWND, DWORD>*)(lParam);
DWORD processId;
if (GetWindowThreadProcessId(hwnd, &processId) && processId == pParams->second)
{
if (IsWindowVisible(hwnd)) {
// Stop enumerating
SetLastError(-1);
pParams->first = hwnd;
return FALSE;
}
return TRUE;
}
// Continue enumerating
return TRUE;
}, (LPARAM)¶ms);
if (!bResult && GetLastError() == -1 && params.first)
{
return params.first;
}
return 0;
}