Attendez la fin d'un processus

206

J'ai une application qui fait

Process.Start()

pour démarrer une autre application 'ABC'. Je veux attendre la fin de cette application (le processus se termine) et continuer mon exécution. Comment puis-je le faire?

Il peut y avoir plusieurs instances de l'application «ABC» en cours d'exécution en même temps.

NLV
la source
Et si vous voulez le faire de manière asynchrone (c'est-à-dire déclencher un événement après la fin), vous pouvez regarder ici SO.
Matt

Réponses:

401

Je pense que vous voulez juste ceci:

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

Voir la page MSDN pour la méthode. Il a également une surcharge où vous pouvez spécifier le délai d'expiration, de sorte que vous n'attendez pas potentiellement indéfiniment.

Noldorin
la source
137

Utiliser Process.WaitForExit? Ou vous abonner à l' Process.Exitedévénement si vous ne souhaitez pas bloquer? Si cela ne fait pas ce que vous voulez, veuillez nous donner plus d'informations sur vos besoins.

Jon Skeet
la source
certainement de bonnes informations avec Process.Exited, mais le PO a dit "attendre"
Mike M
8
@MikeM: C'est pourquoi j'ai fait référence en WaitForExitpremier ... dans certains cas, vous voudrez peut-être exécuter plus de code lorsque quelque chose se termine, mais cela ne signifie pas que vous devez bloquer le thread actuel.
Jon Skeet
7
Si vous comptez utiliser l' Process.Exitedévénement, je pense que vous devez configurer le processus au préalable en définissant la valeur Process.EnableRaisingEventstrue. Cependant, étant donné que cette question a plus de trois ans, il se peut que ce Process.EnableRaisingEventsn'était pas une chose au moment où elle a été posée.
Volonté
Je me suis retrouvé sur cette page à la recherche du nom de l' Process.Exitedévénement. Merci! +1 pour exhaustivité
Tchad
36

Je fais ce qui suit dans ma candidature:

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.

Il y a quelques fonctionnalités supplémentaires qui pourraient vous être utiles ...

AnthonyLambert
la source
17

Vous pouvez utiliser l'attente de sortie ou vous pouvez attraper la propriété HasExited et mettre à jour votre interface utilisateur pour tenir l'utilisateur "informé" (gestion des attentes):

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

J'ai eu un cas où Process.HasExitedn'a pas changé après avoir fermé la fenêtre appartenant au processus. Donc ça Process.WaitForExit()n'a pas marché non plus. J'ai dû surveiller ce Process.Respondingqui est devenu faux après avoir fermé la fenêtre comme ça:

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

Peut-être que cela aide quelqu'un.

Buka
la source
6

Process.WaitForExit devrait être exactement ce que vous cherchez, je pense.

Hans Olsson
la source
1

Se référant à l'exemple de Microsoft: [ https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]

Le mieux serait de définir:

myProcess.EnableRaisingEvents = true;

Sinon, le code sera bloqué. De plus, aucune propriété supplémentaire n'est requise.

// 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}");
}
julien
la source
0

Comme le dit Jon Skeet, utilisez 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
la source
Ne répond pas vraiment à la question. Veuillez affiner votre réponse pour résoudre la question
Grantly
Et maintenant? peut-être ouvrir vb et faire la solution;)
David Lopes
-5

Essaye ça:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();
user3065161
la source
5
À quoi bon commenter une réponse à une question déjà répondue sur la question à laquelle on a déjà répondu? Non seulement vous avez gâché vos propres cycles, mais vous m'avez aussi obligé à perdre le mien.
Jamie Ivanov
Les questions et réponses @AdamBilinski sont destinées à être vues par d'autres personnes qui ont la question non seulement celle qui a posé la question
L3n
4
@ L3n Je suis d'accord, mais cette réponse est exactement la même que la réponse acceptée donc c'est inutile!
Adam Bilinski
@AdamBilinski Oh oui, je n'ai pas bien lu votre commentaire pardonnez-moi xD
L3n