简体   繁体   English

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

[英]Detect if external process is interactive and has any visible UI

I cannot seem to find a way to determine whether a Process has a user interface eg a window, which is visible to the user?我似乎无法找到一种方法来确定Process是否具有用户界面,例如 window,这对用户可见吗?

I would like to differentiate between say Notepad and conhost我想区分 say Notepad 和 conhost

  1. Find out the process ID from your Process instance. 从您的Process实例中查找流程ID。
  2. Enumerate the top-level windows with EnumWindows . 使用EnumWindows枚举顶级窗口。
  3. Call GetWindowThreadProcessId and see if it matches the target PID. 调用GetWindowThreadProcessId ,看看它是否与目标PID匹配。
  4. Call IsWindowVisible and/or IsIconic to test if that window is visible to the user. 调用IsWindowVisible和/或IsIconic来测试该窗口是否对用户可见。

The MSDN article about System.Diagnostics.Process.MainWindowHandle states the following 有关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. 如果您刚刚启动了一个进程并想使用其主窗口句柄,请考虑使用WaitForInputIdle方法以允许该进程完成启动,并确保已创建了主窗口句柄。 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. 他们所暗示的是, Window您所做的呼吁后,可能需要几秒钟来呈现MainWindowHandle ,返回IntPtr.Zero即使你可以清楚地看到一个Window显示。

See https://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx for reference 请参阅https://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx以供参考

Following @David Heffernan, this is what I did:在@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;
}

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

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