Reputation: 6659
I cannot seem to find a way to determine whether a Process
has a user interface e.g. a window, which is visible to the user?
Environment.UserInteractive
is not useful for external processes process.MainWindowHandle != IntPtr.Zero
appears to always return false in my tests?I would like to differentiate between say Notepad and conhost
Upvotes: 1
Views: 2547
Reputation: 13440
Following @David Heffernan, this is what I did:
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;
}
Upvotes: 1
Reputation: 406
The MSDN article about System.Diagnostics.Process.MainWindowHandle
states the following
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.
What they are implying is that the Window
might take several seconds to render after you've made the call for the MainWindowHandle
, returning IntPtr.Zero
even though you can clearly see a Window
is shown.
See https://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx for reference
Upvotes: 2
Reputation: 612993
Process
instance. EnumWindows
. GetWindowThreadProcessId
and see if it matches the target PID.IsWindowVisible
and/or IsIconic
to test if that window is visible to the user.Upvotes: 2