2013-04-24 25 views
7

dies ist mein Code:C# Process.MainWindowHandle gibt immer IntPtr Null

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

Problem ist, dass game.MainWindowHandle ist immer IntPtr.Zero. Ich muss den IntPtr des ran-Prozesses finden, um zu bestätigen, dass das Spiel vom Launcher gestartet wurde, also habe ich das Spiel dazu veranlasst, es IntPtr zu senden und den Launcher reagieren zu lassen, wenn es in Ordnung ist. Aber dazu muss ich den IntPtr des ran-Prozesses genau kennen.

Vielen Dank im Voraus!

Antwort

10

Das Hauptfenster ist das Fenster, das von dem Prozess geöffnet wird, der momentan den Fokus hat (das TopLevel-Formular). Sie müssen die Methode Refresh verwenden, um das Process-Objekt auf zu aktualisieren, um das aktuelle Hauptfenster-Handle zu erhalten, wenn es sich geändert hat.

Sie können die MainWindowHandle-Eigenschaft nur für Prozesse abrufen, die auf dem lokalen Computer ausgeführt werden. Die MainWindowHandle-Eigenschaft ist ein Wert, der das Fenster eindeutig identifiziert, das dem Prozess zugeordnet ist.

Ein Prozess hat nur dann ein Hauptfenster, wenn der Prozess über eine grafische Schnittstelle verfügt. Wenn der zugehörige Prozess kein Hauptfenster hat, ist der MainWindowHandle-Wert Null. Der Wert ist auch Null für Prozesse, die ausgeblendet wurden, dh Prozesse, die in der Taskleiste nicht sichtbar sind. Dies kann bei Prozessen der Fall sein, die als Symbole im Infobereich ganz rechts in der Taskleiste angezeigt werden.

Wenn Sie gerade einen Prozess gestartet haben und das Hauptfenster-Handle verwenden möchten, sollten Sie die WaitForInputIdle-Methode verwenden, um den Start des Prozesses zu ermöglichen und sicherzustellen, dass das Hauptfenster-Handle erstellt wurde. Andernfalls wird eine Ausnahme ausgelöst.

+0

Werden versuchen, dass, wenn ich zu Hause bin. Danke – Kfirprods

+0

Danke, es hat funktioniert. – Kfirprods

+0

Beachten Sie, dass unter 4.5 dies nicht mehr erforderlich ist (anecdotal - mein Code arbeitete auf 4.5 und fehlgeschlagen, wenn ich auf 3.5 sank, bis ich '.Refresh()') – Basic

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

hinzugefügt habe Hallo, Ihr Beitrag wurde als "niedrige Qualität" gekennzeichnet wahrscheinlich, weil es nur aus Code besteht. Sie könnten Ihre Antwort massiv verbessern, indem Sie erklären, wie und warum genau das beantwortet wird. – Ben

3

Eine Abhilfe ist durch alle Fenster der obersten Ebene aufzuzählen und ihre Prozess-IDs prüfen, bis Sie eine Übereinstimmung finden ...


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