【问题标题】:Detect if external process is interactive and has any visible UI检测外部进程是否是交互式的并且有任何可见的 UI
【发布时间】:2015-02-09 09:48:44
【问题描述】:

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

我想区分记事本和主机

【问题讨论】:

  • 没有硬性规定可以确定特定进程是否计划在 5 秒、5 分钟、5 周的时间内打开其第一个窗口。或者,如果它有一些可能会或可能不会强制交互发生的条件逻辑。
  • 顺便说一下,conhost 可能不是一个很好的例子,因为它负责呈现控制台窗口。所以它有一个消息循环等等,根据大多数定义,它是一个 GUI 程序。

标签: c# .net windows winapi process


【解决方案1】:
  1. 从您的 Process 实例中找出进程 ID。
  2. 使用EnumWindows 枚举顶级窗口。
  3. 调用GetWindowThreadProcessId,看看是否匹配目标PID。
  4. 致电IsWindowVisible 和/或IsIconic 以测试该窗口是否对用户可见。

【讨论】:

  • 可能无法按预期工作,因为控制台窗口(有时?)的 IIRC GetWindowThreadProcessId() 返回附加到该控制台的命令行进程。我假设控制台窗口在这种情况下算作顶级窗口。我不确定如何最好地过滤掉这些。
  • 还没有实际测试过,但希望这些 winapi 调用可以从服务中工作
  • 不,他们没有。请记住,服务在与交互式用户会话不同的会话中运行。并且会话是孤立的。
【解决方案2】:

关于System.Diagnostics.Process.MainWindowHandle 的 MSDN 文章陈述如下

如果您刚刚启动了一个进程并想使用它的主窗口句柄,请考虑使用 WaitForInputIdle 方法让该进程完成启动,确保已创建主窗口句柄。否则会抛出异常。

他们的意思是,在您调用 MainWindowHandle 后,Window 可能需要几秒钟才能呈现,即使您可以清楚地看到显示了 Window,也会返回 IntPtr.Zero

参考https://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle(v=vs.110).aspx

【讨论】:

【解决方案3】:

在@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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-22
    • 2020-05-22
    • 2021-12-12
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    相关资源
    最近更新 更多