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.


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.


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.


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 ...


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

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.



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

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

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();

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.