Attendere il termine di un processo


206

Ho un'applicazione che lo fa

Process.Start()

per avviare un'altra applicazione 'ABC'. Voglio aspettare fino alla fine dell'applicazione (il processo termina) e continuare la mia esecuzione. Come posso farlo?

Possono esserci più istanze dell'applicazione 'ABC' in esecuzione contemporaneamente.


E se vuoi farlo in modo asincrono (ovvero generare un evento dopo il completamento), puoi guardare qui SO.
Matt

Risposte:


401

Penso che tu voglia solo questo:

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

Vedere la pagina MSDN per il metodo. Ha anche un sovraccarico in cui è possibile specificare il timeout, quindi potenzialmente non si attende per sempre.


137

Usare Process.WaitForExit? O iscriviti Process.Exitedall'evento se non vuoi bloccare? Se ciò non fa quello che vuoi, ti preghiamo di darci maggiori informazioni sui tuoi requisiti.


sicuramente buone informazioni con Process.Exited, ma l'OP ha detto "aspetta"
Mike M

8
@MikeM: Ecco perché ho fatto riferimento WaitForExitprima ... in alcuni casi potresti voler eseguire più codice quando qualcosa finisce, ma ciò non significa che devi bloccare il thread corrente.
Jon Skeet,

7
Se hai intenzione di utilizzare l' Process.Exitedevento, credo che devi configurare il processo in anticipo impostando Process.EnableRaisingEventssu true. Tuttavia, considerando che questa domanda ha più di tre anni, potrebbe non essere Process.EnableRaisingEventsstata una cosa al momento in cui è stata posta.
Sarà

Sono finito in questa pagina alla ricerca del nome Process.Exiteddell'evento. Grazie! +1 per completezza
Ciad

36

Faccio quanto segue nella mia domanda:

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.

Ci sono alcune funzionalità extra che potresti trovare utili ...


17

È possibile utilizzare wait for exit oppure acquisire la proprietà HasExited e aggiornare l'interfaccia utente per mantenere l'utente "informato" (gestione delle aspettative):

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

9

Ho avuto un caso in cui Process.HasExitednon è cambiato dopo aver chiuso la finestra appartenente al processo. Quindi Process.WaitForExit()anche non ha funzionato. Ho dovuto monitorare Process.Respondingche è diventato falso dopo aver chiuso la finestra in quel modo:

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

Forse questo aiuta qualcuno.



1

Facendo riferimento all'esempio Microsoft: [ https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]

La cosa migliore sarebbe impostare:

myProcess.EnableRaisingEvents = true;

altrimenti il ​​codice verrà bloccato. Inoltre non sono necessarie proprietà aggiuntive.

// 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}");
}

0

Come dice Jon Skeet, usa 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);
}

Non risponde davvero alla domanda. Per favore, affina la tua risposta per risolvere la domanda
Grantly

E adesso? forse apri vb e crea la soluzione;)
David Lopes,

-5

Prova questo:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();

5
Qual è il punto di commentare una risposta a una domanda già risposta sulla domanda a cui è già stata data una risposta? Non solo hai sprecato i tuoi cicli ma mi hai costretto a sprecare anche i miei.
Jamie Ivanov,

Le domande e le risposte di @AdamBilinski sono destinate ad essere viste da altre persone che hanno la domanda non solo quella che ha posto
L3n

4
@ L3n Sono d'accordo, ma questa risposta è esattamente la stessa della risposta accettata, quindi è inutile!
Adam Bilinski,

@AdamBilinski Oh sì, non hai letto bene il tuo commento, perdonami xD
L3n
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.