Espera hasta que termine un proceso

206

Tengo una aplicación que hace

Process.Start()

para iniciar otra aplicación 'ABC'. Quiero esperar hasta que la aplicación finalice (el proceso muere) y continuar con mi ejecución. ¿Cómo puedo hacerlo?

Puede haber varias instancias de la aplicación 'ABC' ejecutándose al mismo tiempo.

NLV
fuente
Y si desea hacerlo de forma asincrónica (es decir, generar un evento después de la finalización), puede mirar aquí en SO.
Matt

Respuestas:

401

Creo que solo quieres esto:

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

Vea la página de MSDN para el método. También tiene una sobrecarga donde puede especificar el tiempo de espera, por lo que potencialmente no está esperando para siempre.

Noldorin
fuente
137

Uso Process.WaitForExit? ¿O suscribirse al Process.Exitedevento si no desea bloquear? Si eso no hace lo que desea, bríndenos más información sobre sus requisitos.

Jon Skeet
fuente
definitivamente buena información con Process.Exited, pero el OP dijo "espera"
Mike M
8
@MikeM: Por eso me referí WaitForExitprimero ... en algunos casos, es posible que desee ejecutar más código cuando algo termine, pero eso no significa que deba bloquear el hilo actual.
Jon Skeet
77
Si va a utilizar el Process.Exitedevento, creo que debe configurar el proceso de antemano estableciéndolo Process.EnableRaisingEventsen verdadero. Sin embargo, teniendo en cuenta que esta pregunta tiene más de tres años, puede ser que Process.EnableRaisingEventsno era una cosa en el momento en que se hizo.
Será
Terminé en esta página buscando el nombre del Process.Exitedevento. ¡Gracias! +1 para completar
Chad
36

Hago lo siguiente en mi solicitud:

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.

Hay algunas características adicionales allí que pueden serle útiles ...

AnthonyLambert
fuente
17

Puede usar esperar para salir o puede capturar la propiedad HasExited y actualizar su IU para mantener al usuario "informado" (gestión de expectativas):

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

Tuve un caso en el Process.HasExitedque no cambió después de cerrar la ventana perteneciente al proceso. Entonces Process.WaitForExit()tampoco funcionó. Tuve que controlar Process.Respondingque fue falso después de cerrar la ventana así:

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

Quizás esto ayude a alguien.

Buka
fuente
1

En referencia al ejemplo de Microsoft: [ https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]

Lo mejor sería establecer:

myProcess.EnableRaisingEvents = true;

de lo contrario, el Código será bloqueado. Además, no se necesitan propiedades adicionales.

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

Como dice Jon Skeet, use el 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
fuente
Realmente no responde la pregunta. Por favor, refina tu respuesta para resolver la pregunta
Grantly
¿Y ahora? tal vez abra vb y haga la solución;)
David Lopes
-5

Prueba esto:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();
usuario3065161
fuente
55
¿De qué sirve comentar una respuesta a una pregunta ya respondida sobre la pregunta que ya se está respondiendo? No solo has desperdiciado tus propios ciclos, sino que también me has obligado a desperdiciar los míos.
Jamie Ivanov
Las preguntas y respuestas de @AdamBilinski están destinadas a ser vistas por otras personas que tienen la pregunta, no solo la que preguntó
L3n
44
@ L3n Estoy de acuerdo, pero esta respuesta es exactamente la misma que la respuesta aceptada, ¡así que no tiene sentido!
Adam Bilinski
@AdamBilinski Oh, sí, no leyó su comentario correctamente perdóname xD
L3n