How can I tell if a process has a graphical interface?

前端 未结 4 993
夕颜
夕颜 2021-01-11 16:16

I\'m using automation to test an application, but sometimes I want to start the application via a batch file. When I run \"process.WaitForInputIdle(100)\" I get an error:

4条回答
  •  醉酒成梦
    2021-01-11 16:57

    As well as a MainWindowHandle check, one can enumerate the process threads and check if any of them reference a visible window via P/Invokes. This seems to do a good job catching any windows that the first check misses.

    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 results = new List();
    
    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);
    

提交回复
热议问题