11

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

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

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

4

4 回答 4

10

请参阅Environment.UserInteractive。这将识别进程是否有接口,例如服务不是用户交互的。

您还可以查看Process.MainWindowHandle,它会告诉您是否有图形界面。

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

于 2010-09-24T09:21:33.710 回答
1

您可以简单地尝试捕获异常:

Process process = ...
try
{
    process.WaitForInputIdle(100);
}
catch (InvalidOperationException ex)
{
    // no graphical interface
}
于 2010-09-24T09:29:21.617 回答
1

我是这样想的,仍然很丑,但尽量避免例外。

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;
    }
}
于 2010-09-24T11:25:16.130 回答
1

除了MainWindowHandle检查之外,还可以枚举进程线程并检查它们中的任何一个是否通过 P/Invokes 引用可见窗口。这似乎可以很好地捕捉第一次检查遗漏的任何窗口。

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);
于 2017-03-12T04:51:31.410 回答