Feedback

C# - Process: Warten dass das MainWindow erstellt wurde

Veröffentlicht von am 28.07.2015
(0 Bewertungen)
Wenn man ein Programm startet um später mit seiner GUI zu interagieren sollte man zunächst prüfen ob das Hauptfenster bereits erstellt wurde.
Diese Erweiterungsmethode vereinfacht das ein wenig.
Snippet in VB übersetzen
namespace System.Diagnostics
{
    using System;
    using System.Threading;

    public static class Process_Extensions
    {
        /// <summary>
        /// Wartet solange bis das MainWindow des Prozesses erzeugt wurde.
        /// </summary>
        /// <param name="process">Der Prozess dessen MainWindow erzeugt werden soll.</param>
        /// <returns><c>true</c> wenn der Prozess läuft und ein MainWindow hat; andernfalls <c>false</c></returns>
        public static bool WaitForMainWindow(this Process process)
        {
            while (!process.HasExited && process.MainWindowHandle == IntPtr.Zero)
                Thread.Sleep(10);
            return !process.HasExited;
        }

        /// <summary>
        /// Wartet solange bis das MainWindow des Prozesses erzeugt wurde, aber maximal <paramref name="timeout"/> Millisekunden.
        /// </summary>
        /// <param name="process">Der Prozess dessen MainWindow erzeugt werden soll.</param>
        /// <param name="timeout">Die Zeit in Millisekunden die maximal gewartet werden soll, bevor die Methode zurück kehrt.</param>
        /// <returns><c>true</c> wenn der Prozess läuft und ein MainWindow hat; andernfalls <c>false</c></returns>
        public static bool WaitForMainWindow(this Process process,uint timeout)
        {
            var start = DateTime.Now;
            while (!process.HasExited && process.MainWindowHandle == IntPtr.Zero)
            {
                Thread.Sleep(10);
                if ((DateTime.Now - start).TotalMilliseconds >= timeout)
                {
                    return false;
                }
            }
            return !process.HasExited;
        }
    }
}
Abgelegt unter Process, Automation, MainWindow, Handle, Start.

2 Kommentare zum Snippet

Thomas Roskop schrieb am 17.08.2015:
Hallo Koopakiller,
nettes Snippet.

Frage mich nur, was passiert, wenn die andere Anwendung in einen Deadlock kommt und deshalb nicht beendet wird aber auch kein Hauptfenster aufbaut. Und wenn der Benutzer dann auch nicht in der Lage ist das Programm zu beenden, wird es durchaus etwas ungünstig.

Mein Vorschlag wäre es, einen Timeout einzubauen:

public enum Wait_Result {
Success, // Die UI der Anwendung ist bereit
Timeout, // Die Anwendung wurde nicht korrekt gestartet, Zeitüberschreitung
Failed // Die App wurde unerwartet beendet
}


public static Wait_Result WaitForProcessMainWindow(this Process process)
{
// Maximal 20 durchläufe (10 * 200ms = 2000ms = 2Sekunden)
// d.h., dass der Timeout nach 2Sekunden eintritt.
const int TIMEOUT_COUNT = 200;
const int WAIT_TIME = 10; // Jeweils 10ms warten

int c = 0;
while (!process.HasExited && process.MainWindowHandle == IntPtr.Zero) {
c++; // Counter erhöhen
if(c > TIMEOUT_COUNT) // Timeout festgestellt
return Wait_Result.Timeout;
Thread.Sleep(WAIT_TIME);
}

// Zurückgeben, ob die Anwendung bereit ist.
return (process.HasExited ? Wait_Result.Failed : Wait_Result.Success);
}

Koopakiller schrieb am 17.08.2015:
Ich habe mal eine Version mit einer Timeout Variablen eingebaut. Ich denke das sich jeder das Enum selbst einbauen kann der will. Ich habe die Methode mehr im Stil der WaitForExit-Methode gehalten.
 

Logge dich ein, um hier zu kommentieren!