代码之家  ›  专栏  ›  技术社区  ›  Lunivore

如何判断流程是否具有图形界面?

  •  9
  • Lunivore  · 技术社区  · 14 年前

    我正在使用自动化测试应用程序,但有时我想通过批处理文件启动应用程序。当我运行“process.waitforinputidle(100)”时,我得到一个错误:

    “WaitForInputIdle失败。这可能是因为进程没有图形界面。”

    如何判断流程是否具有图形界面?

    4 回复  |  直到 7 年前
        1
  •  7
  •   Paul Ruane    14 年前

    Environment.UserInteractive . 这将确定流程是否有接口,例如服务不是用户交互的。

    你也可以看看 Process.MainWindowHandle 它将告诉您是否有图形界面。

    这两项检查的结合应涵盖所有可能性。

        2
  •  0
  •   Dirk Vollmar    14 年前

    您只需尝试捕获异常:

    Process process = ...
    try
    {
        process.WaitForInputIdle(100);
    }
    catch (InvalidOperationException ex)
    {
        // no graphical interface
    }
    
        3
  •  0
  •   Bear Monkey    14 年前

    我一直在这样想,虽然还是很难看,但还是尽量避免例外。

    Process process = ...
    
    bool hasUI = false;
    
    if (!process.HasExited)
    {
        try
        {
            hasUI = process.MainWindowHandle != IntPtr.Zero;
        }
        catch (InvalidOperationException)
        {
            if (!process.HasExited)
                throw;
        }
    }
    
    if (!process.HasExited && hasUI)
    {
    
        try
        {
            process.WaitForInputIdle(100);
        }
        catch (InvalidOperationException)
        {
            if (!process.HasExited)
                throw;
        }
    }
    
        4
  •  0
  •   Zachary Canann    7 年前

    以及 MainWindowHandle 检查,可以枚举进程线程,并通过p/invoke检查它们是否引用可见窗口。这似乎能很好地捕捉到第一次检查漏掉的任何窗口。

    private Boolean isProcessWindowed(Process externalProcess)
    {
        if (externalProcess.MainWindowHandle != IntPtr.Zero)
        {
            return true;
        }
    
        foreach (ProcessThread threadInfo in externalProcess.Threads)
        {
            IntPtr[] windows = GetWindowHandlesForThread(threadInfo.Id);
    
            if (windows != null)
            {
                foreach (IntPtr handle in windows)
                {
                    if (IsWindowVisible(handle))
                    {
                        return true;
                    }
                }
            }
        }
    
        return false;
    }
    
    private IntPtr[] GetWindowHandlesForThread(int threadHandle)
    {
        results.Clear();
        EnumWindows(WindowEnum, threadHandle);
    
        return results.ToArray();
    }
    
    private delegate int EnumWindowsProc(IntPtr hwnd, int lParam);
    
    private List<IntPtr> results = new List<IntPtr>();
    
    private int WindowEnum(IntPtr hWnd, int lParam)
    {
        int processID = 0;
        int threadID = GetWindowThreadProcessId(hWnd, out processID);
        if (threadID == lParam)
        {
            results.Add(hWnd);
        }
    
        return 1;
    }
    
    [DllImport("user32.Dll")]
    private static extern int EnumWindows(EnumWindowsProc x, int y);
    [DllImport("user32.dll")]
    public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
    [DllImport("user32.dll")]
    static extern bool IsWindowVisible(IntPtr hWnd);