Poczekaj na zakończenie procesu

206

Mam aplikację, która ma

Process.Start()

aby uruchomić kolejną aplikację „ABC”. Chcę poczekać, aż aplikacja się zakończy (proces umiera) i kontynuować wykonywanie. Jak mogę to zrobić?

Jednocześnie może być uruchomionych wiele wystąpień aplikacji „ABC”.

NLV
źródło
A jeśli chcesz to zrobić asynchronicznie (tj. Wywołać zdarzenie po zakończeniu), możesz spojrzeć tutaj na SO.
Matt

Odpowiedzi:

401

Myślę, że po prostu chcesz tego:

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

Metodę można znaleźć na stronie MSDN . Ma również przeciążenie, w którym możesz określić limit czasu, więc potencjalnie nie czekasz wiecznie.

Noldorin
źródło
137

Użyć Process.WaitForExit? Lub zasubskrybuj Process.Exitedwydarzenie, jeśli nie chcesz blokować? Jeśli to nie pomoże, podaj nam więcej informacji o swoich wymaganiach.

Jon Skeet
źródło
zdecydowanie dobre informacje z Process.Exited, ale OP powiedział „czekać”
Mike M
8
@MikeM: Właśnie dlatego wspomniałem WaitForExitpierwszy ... w niektórych przypadkach możesz chcieć wykonać więcej kodu, gdy coś się skończy, ale to nie znaczy, że musisz zablokować bieżący wątek.
Jon Skeet
7
Jeśli zamierzasz skorzystać ze Process.Exitedzdarzenia, uważam, że musisz wcześniej skonfigurować proces, ustawiając wartość Process.EnableRaisingEventstrue. Chociaż biorąc pod uwagę, że to pytanie ma ponad trzy lata, być może Process.EnableRaisingEventsnie było to w chwili zadawania pytania .
Czy
Znalazłem się na tej stronie, szukając nazwy Process.Exitedwydarzenia. Dzięki! +1 za kompletność
Czad
36

W mojej aplikacji wykonuję następujące czynności:

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.

Jest tam kilka dodatkowych funkcji, które mogą być przydatne ...

Anthony Lambert
źródło
17

Możesz użyć opcji oczekiwania na wyjście lub złapać właściwość HasExited i zaktualizować interfejs użytkownika, aby użytkownik był „poinformowany” (zarządzanie oczekiwaniami):

System.Diagnostics.Process process = System.Diagnostics.Process.Start("cmd.exe");
while (!process.HasExited)
{
    //update UI
}
//done
riffnl
źródło
9

Miałem przypadek, w którym Process.HasExitednie zmieniłem się po zamknięciu okna należącego do procesu. Więc Process.WaitForExit()też nie działało. Process.RespondingPo zamknięciu okna musiałem monitorować, czy nie jest to fałsz:

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

Być może to pomaga komuś.

Buka
źródło
1

Nawiązując do przykładu Microsoft: [ https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]

Najlepiej byłoby ustawić:

myProcess.EnableRaisingEvents = true;

w przeciwnym razie kod zostanie zablokowany. Również żadne dodatkowe właściwości nie są potrzebne.

// 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}");
}
juliański
źródło
0

Jak mówi Jon Skeet, użyj 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
źródło
Naprawdę nie odpowiada na pytanie. Uściślij swoją odpowiedź, aby rozwiązać pytanie
Grantly
I teraz? może otwórz vb i dokonaj rozwiązania;)
David Lopes,
-5

Spróbuj tego:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();
użytkownik3065161
źródło
5
Jaki jest sens komentowania odpowiedzi na pytanie, na które już udzielono odpowiedzi, na pytanie, na które już udzielono odpowiedzi? Nie tylko zmarnowałeś własne cykle, ale także zmusiłeś mnie do marnowania kopalni.
Jamie Iwanow
@AdamBilinski pytania i odpowiedzi mają być widoczne dla innych osób, które mają pytanie nie tylko ten, który zadał
L3n
4
@ L3n Zgadzam się, ale ta odpowiedź jest dokładnie taka sama jak odpowiedź zaakceptowana, więc jest bezcelowa!
Adam Biliński
@AdamBilinski O tak, nie przeczytałem waszego komentarza właściwie
wybaczcie