2013-04-24 7 views
7

это мой код:C# Process.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(); 
       } 
      } 

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

Заранее благодарен!

ответ

10

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

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

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

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

+0

Попробую, что, когда я дома. Спасибо – Kfirprods

+0

Спасибо, это сработало. – Kfirprods

+0

Обратите внимание, что на 4.5 это больше не требуется (анекдотично - мой код работал на 4.5 и не удался, когда я опустился до 3.5, пока не добавил '.Refresh()') – Basic

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

Привет, ваше сообщение было помечено как «низкое качество», вероятно, потому, что он состоит исключительно из кода. Вы могли бы значительно улучшить свой ответ, объяснив, как именно и почему это отвечает на вопрос? – Ben

3

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


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

 Смежные вопросы

  • Нет связанных вопросов^_^