Как я могу сказать, имеет ли процесс графический интерфейс?

Я использую автоматизацию для тестирования приложения, но иногда я хочу запустить приложение через пакетный файл. Когда я запускаю "процесс.WaitForInputIdle(100)" я получаю сообщение об ошибке:

"WaitForInputIdle не удалось. Это может быть связано с тем, что процесс не имеет графического интерфейса."

Как я могу сказать, имеет ли процесс графический интерфейс или нет?

4 ответов


посмотреть окружающая среда.В описании свойства userinteractive. Это позволит определить, имеет ли процесс интерфейс вообще, например, службы не являются интерактивными для пользователей.

вы также можете посмотреть на


вы можете просто попытаться поймать исключение:

Process process = ...
try
{
    process.WaitForInputIdle(100);
}
catch (InvalidOperationException ex)
{
    // no graphical interface
}

Я думал в этом направлении, все еще уродливый, но пытается избежать исключений.

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

а также MainWindowHandle check, можно перечислить потоки процесса и проверить, ссылается ли какой-либо из них на видимое окно через 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);