Процесс C#.MainWindowHandle всегда возвращает IntPtr ноль

Это мой код:

            using (Process game = Process.Start(new ProcessStartInfo() { 
        FileName="DatabaseCheck.exe",
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        UseShellExecute = false }))
        {
            lblLoad.Text = "Loading";
            int Switch = 0;

            while (game.MainWindowHandle == IntPtr.Zero)
            {
                Switch++;
                if (Switch % 1000 == 0)
                {
                    lblLoad.Text += ".";
                    if (lblLoad.Text.Contains("...."))
                        lblLoad.Text = "Loading.";

                    lblLoad.Update();
                    game.Refresh();
                }
            }

проблема в том, что игра.MainWindowHandle всегда IntPtr.Нуль. Мне нужно найти IntPtr запущенного процесса, чтобы подтвердить, что игра была запущена пусковой установкой, поэтому я заставил игру отправить ее IntPtr и позволить пусковой установке ответить, если все в порядке. Но для этого я должен знать IntPtr процесса ran конкретно.

спасибо заранее!

3 ответов


главное окно-это окно, открытое процессом, который в настоящее время имеет фокус (форма верхнего уровня). Вы должны использовать Refresh метод обновления объекта процесса до получить текущий дескриптор главного окна, если он изменился.

Вы можете узнать MainWindowHandle свойство только для процессов, запущенных на локальном компьютере. Свойство MainWindowHandle-это значение, однозначно идентифицирующее окно, связанное с процесс.

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

если у вас есть только что запустил процесс и хотите использовать его дескриптор главного окна, рассмотрите возможность использования WaitForInputIdle метод, чтобы позволить процессу завершить запуск, гарантируя, что дескриптор главного окна был создан. В противном случае будет создано исключение.


обходной путь-перечислить все окна верхнего уровня и изучить их идентификаторы процессов, пока не найдете совпадение...


    [DllImport("user32.dll")]
    public static extern IntPtr FindWindowEx(IntPtr parentWindow, IntPtr previousChildWindow, string windowClass, string windowTitle);

    [DllImport("user32.dll")]
    private static extern IntPtr GetWindowThreadProcessId(IntPtr window, out int process);

    private IntPtr[] GetProcessWindows(int process) {
        IntPtr[] apRet = (new IntPtr[256]);
        int iCount = 0;
        IntPtr pLast = IntPtr.Zero;
        do {
            pLast = FindWindowEx(IntPtr.Zero, pLast, null, null);
            int iProcess_;
            GetWindowThreadProcessId(pLast, out iProcess_);
            if(iProcess_ == process) apRet[iCount++] = pLast;
        } while(pLast != IntPtr.Zero);
        System.Array.Resize(ref apRet, iCount);
        return apRet;
    }

while (!proc.HasExited)
{
    proc.Refresh();
    if (proc.MainWindowHandle.ToInt32() != 0)
    {
        return proc.MainWindowHandle;
    }
}