Warten Sie, bis ein Vorgang beendet ist

206

Ich habe eine Anwendung, die tut

Process.Start()

um eine andere Anwendung 'ABC' zu starten. Ich möchte warten, bis diese Anwendung endet (Prozess stirbt) und meine Ausführung fortsetzen. Wie kann ich es tun?

Möglicherweise werden mehrere Instanzen der Anwendung 'ABC' gleichzeitig ausgeführt.

NLV
quelle
Und wenn Sie es asynchron machen möchten (dh ein Ereignis nach Abschluss auslösen), können Sie sich hier SO ansehen .
Matt

Antworten:

401

Ich denke du willst nur das:

var process = Process.Start(...);
process.WaitForExit();

Informationen zur Methode finden Sie auf der MSDN-Seite . Es hat auch eine Überlastung, in der Sie das Zeitlimit angeben können, sodass Sie möglicherweise nicht ewig warten müssen.

Noldorin
quelle
137

Verwenden Process.WaitForExit? Oder abonnieren Sie die Process.ExitedVeranstaltung, wenn Sie nicht blockieren möchten? Wenn das nicht Ihren Wünschen entspricht, geben Sie uns bitte weitere Informationen zu Ihren Anforderungen.

Jon Skeet
quelle
definitiv gute Infos mit Process.Exited, aber das OP sagte "warte"
Mike M
8
@MikeM: Deshalb habe ich zuerst darauf hingewiesen WaitForExit... in einigen Fällen möchten Sie möglicherweise mehr Code ausführen, wenn etwas fertig ist, aber das bedeutet nicht, dass Sie den aktuellen Thread blockieren müssen.
Jon Skeet
7
Wenn Sie das Process.ExitedEreignis verwenden möchten, müssen Sie den Prozess meines Erachtens im Voraus konfigurieren, indem Sie ihn Process.EnableRaisingEventsauf true setzen. Wenn man bedenkt, dass diese Frage älter als drei Jahre ist, kann es sein, dass dies Process.EnableRaisingEventszum Zeitpunkt der Beantwortung noch nicht der Fall war.
Will
Ich bin auf dieser Seite gelandet und habe nach dem Namen der Process.ExitedVeranstaltung gesucht . Vielen Dank! +1 der Vollständigkeit
Chad
36

In meiner Bewerbung mache ich Folgendes:

Process process = new Process();
process.StartInfo.FileName = executable;
process.StartInfo.Arguments = arguments;
process.StartInfo.ErrorDialog = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
process.Start();
process.WaitForExit(1000 * 60 * 5);    // Wait up to five minutes.

Es gibt ein paar zusätzliche Funktionen, die Sie vielleicht nützlich finden ...

Anthony Lambert
quelle
17

Sie können das Warten auf das Beenden verwenden oder die HasExited-Eigenschaft abfangen und Ihre Benutzeroberfläche aktualisieren, um den Benutzer "informiert" zu halten (Erwartungsverwaltung):

System.Diagnostics.Process process = System.Diagnostics.Process.Start("cmd.exe");
while (!process.HasExited)
{
    //update UI
}
//done
riffnl
quelle
9

Ich hatte einen Fall, in dem Process.HasExitedsich nach dem Schließen des zum Prozess gehörenden Fensters nichts geändert hat. Also Process.WaitForExit()auch nicht funktioniert. Ich musste überwachen, Process.Respondingdass es nach dem Schließen des Fensters falsch lief:

while (!_process.HasExited && _process.Responding) {
  Thread.Sleep(100);
}
...

Vielleicht hilft das jemandem.

Buka
quelle
6

Process.WaitForExit sollte genau das sein, wonach Sie suchen, denke ich.

Hans Olsson
quelle
1

Bezugnehmend auf das Microsoft-Beispiel: [ https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]

Am besten setzen Sie:

myProcess.EnableRaisingEvents = true;

Andernfalls wird der Code blockiert. Auch keine zusätzlichen Eigenschaften erforderlich.

// Start a process and raise an event when done.
myProcess.StartInfo.FileName = fileName;
// Allows to raise event when the process is finished
myProcess.EnableRaisingEvents = true;
// Eventhandler wich fires when exited
myProcess.Exited += new EventHandler(myProcess_Exited);
// Starts the process
myProcess.Start();

// Handle Exited event and display process information.
private void myProcess_Exited(object sender, System.EventArgs e)
{
Console.WriteLine(
                  $"Exit time    : {myProcess.ExitTime}\n" +
                  $"Exit code    : {myProcess.ExitCode}\n" +
                  $"Elapsed time : {elapsedTime}");
}
julianisch
quelle
0

Verwenden Sie, wie Jon Skeet sagt, Folgendes Process.Exited:

proc.StartInfo.FileName = exportPath + @"\" + fileExe;
proc.Exited += new EventHandler(myProcess_Exited);
proc.Start();
inProcess = true;

while (inProcess)
{
    proc.Refresh();
    System.Threading.Thread.Sleep(10);
    if (proc.HasExited)
    {
        inProcess = false;
    }
}

private void myProcess_Exited(object sender, System.EventArgs e)
{
    inProcess = false;
    Console.WriteLine("Exit time:    {0}\r\n" +
      "Exit code:    {1}\r\n", proc.ExitTime, proc.ExitCode);
}
David Lopes
quelle
Beantwortet die Frage nicht wirklich. Bitte verfeinern Sie Ihre Antwort, um die Frage zu lösen
Grantly
Und nun? vielleicht öffnen Sie vb und machen Sie die Lösung;)
David Lopes
-5

Versuche dies:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();
user3065161
quelle
5
Was bringt es, eine Antwort auf eine bereits beantwortete Frage zu der bereits beantworteten Frage zu kommentieren? Sie haben nicht nur Ihre eigenen Zyklen verschwendet, sondern mich auch gezwungen, meine zu verschwenden.
Jamie Ivanov
@ AdamBilinski Fragen und Antworten sollen von anderen Personen gesehen werden, die die Frage haben, nicht nur derjenige, der gefragt hat
L3n
4
@ L3n Ich stimme zu, aber diese Antwort ist genau die gleiche wie die akzeptierte Antwort, also ist es sinnlos!
Adam Bilinski
@ AdamBilinski Oh ja, habe deinen Kommentar nicht richtig gelesen, vergib mir xD
L3n