检测外部进程是否是交互式的并且是否有任何可见的 UI

Detect if external process is interactive and has any visible UI

我似乎无法找到一种方法来确定 Process 是否具有用户界面,例如a window,哪个对用户可见?

我想区分 say Notepad 和 conhost

  1. 从您的 Process 实例中找出进程 ID。
  2. EnumWindows枚举顶级windows。
  3. 调用GetWindowThreadProcessId,看是否匹配目标PID。
  4. 调用 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)&params);

    if (!bResult && GetLastError() == -1 && params.first)
    {
        return params.first;
    }

    return 0;
}