C # – Hacer un proceso. Empieza a esperar hasta que el proceso comience.

Necesito asegurarme de que se está ejecutando un proceso antes de continuar con un método.

La statement es:

Process.Start("popup.exe"); 

¿Puedes hacer un comando WAIT o establecer un retraso en este valor?

¿Quieres decir esperar hasta que termine? Luego use Process.WaitForExit :

 var process = new Process { StartInfo = new ProcessStartInfo { FileName = "popup.exe" } }; process.Start(); process.WaitForExit(); 

Alternativamente, si se trata de una aplicación con una IU que está esperando ingresar en un bucle de mensaje, puede decir:

 process.Start(); process.WaitForInputIdle(); 

Por último, si ninguno de estos se aplica, solo Thread.Sleep por un tiempo razonable:

 process.Start(); Thread.Sleep(1000); // sleep for one second 

También lo necesitaba una vez, e hice un control en el título de la ventana del proceso. Si es el que espera, puede estar seguro de que la aplicación se está ejecutando. La aplicación que estaba revisando necesitaba algo de tiempo para el inicio y este método funcionó bien para mí.

 var process = Process.Start("popup.exe"); while(process.MainWindowTitle != "Title") { Thread.Sleep(10); } 

La respuesta de ‘ChrisG’ es correcta, pero tenemos que actualizar MainWindowTitle cada vez y es mejor verificar si está vacío … así:

 var proc = Process.Start("popup.exe"); while (string.IsNullOrEmpty(proc.MainWindowTitle)) { System.Threading.Thread.Sleep(100); proc.Refresh(); } 

Al igual que otros ya han dicho, no es inmediatamente obvio lo que estás preguntando. Voy a suponer que quieres iniciar un proceso y luego realizar otra acción cuando el proceso “esté listo”.

Por supuesto, el “está listo” es el truco. Dependiendo de cuáles sean sus necesidades, puede descubrir que simplemente esperar es suficiente. Sin embargo, si necesita una solución más robusta, puede considerar usar un Mutex con nombre para controlar el flujo de control entre sus dos procesos.

Por ejemplo, en su proceso principal, puede crear un mutex con nombre e iniciar un hilo o tarea que esperará. Entonces, puedes comenzar el segundo proceso. Cuando ese proceso decide que “está listo”, puede abrir el mutex con nombre (debe usar el mismo nombre, por supuesto) y enviar la señal al primer proceso.

Estoy de acuerdo con Tom Además, para verificar los procesos mientras se realiza Thread.Sleep, verifique los procesos en ejecución. Algo como:

 bool found = 0; while (!found) { foreach (Process clsProcess in Process.GetProcesses()) if (clsProcess.Name == Name) found = true; Thread.CurrentThread.Sleep(1000); } 

Antes que nada: sé que esto es bastante antiguo, pero todavía no hay una respuesta aceptada, por lo que quizás mi enfoque ayude a otra persona. 🙂

Lo que hice para resolver esto es:

 process.Start(); while (true) { try { var time = process.StartTime; break; } catch (Exception) {} } 

La asociación var time = process.StartTime lanzará una excepción siempre que el proceso no se inicie. Entonces, una vez que se aprueba, es seguro asumir que el proceso se está ejecutando y trabajar más con él. Estoy usando esto para esperar a que se inicie el proceso de Java, ya que lleva algo de tiempo. De esta forma, debería ser independiente de la máquina que ejecuta la aplicación en lugar de usar Thread.Sleep() .

Entiendo que esta no es una solución muy limpia, pero la única que debería ser independiente del rendimiento podría pensar.

¿Estás seguro de que el método Start regresa antes de que comience el proceso hijo? Siempre tuve la impresión de que Start inicia el proceso hijo sincrónicamente.

Si desea esperar hasta que su proceso hijo termine algún tipo de inicialización, entonces necesita comunicación entre procesos; consulte Comunicación interproceso para Windows en C # (.NET 2.0) .

Para extender un poco la idea de @ ChrisG, considere usar process.MainWindowHandle y ver si el mensaje de la ventana está respondiendo. Utilice p / invocar esta API de Win32: SendMessageTimeout . Desde ese enlace:

Si la función tiene éxito, el valor devuelto es distinto de cero. SendMessageTimeout no proporciona información sobre el tiempo de espera de las ventanas individuales si se utiliza HWND_BROADCAST.

Si la función falla o expira, el valor de retorno es 0. Para obtener información extendida sobre el error, llame a GetLastError. Si GetLastError devuelve ERROR_TIMEOUT, la función agotó el tiempo de espera.

Aquí una implementación que usa un System.Threading.Timer . Tal vez un poco demasiado para su propósito.

  private static bool StartProcess(string filePath, string processName) { if (!File.Exists(filePath)) throw new InvalidOperationException($"Unknown filepath: {(string.IsNullOrEmpty(filePath) ? "EMPTY PATH" : filePath)}"); var isRunning = false; using (var resetEvent = new ManualResetEvent(false)) { void Callback(object state) { if (!IsProcessActive(processName)) return; isRunning = true; // ReSharper disable once AccessToDisposedClosure resetEvent.Set(); } using (new Timer(Callback, null, 0, TimeSpan.FromSeconds(0.5).Milliseconds)) { Process.Start(filePath); WaitHandle.WaitAny(new WaitHandle[] { resetEvent }, TimeSpan.FromSeconds(9)); } } return isRunning; } private static bool StopProcess(string processName) { if (!IsProcessActive(processName)) return true; var isRunning = true; using (var resetEvent = new ManualResetEvent(false)) { void Callback(object state) { if (IsProcessActive(processName)) return; isRunning = false; // ReSharper disable once AccessToDisposedClosure resetEvent.Set(); } using (new Timer(Callback, null, 0, TimeSpan.FromSeconds(0.5).Milliseconds)) { foreach (var process in Process.GetProcessesByName(processName)) process.Kill(); WaitHandle.WaitAny(new WaitHandle[] { resetEvent }, TimeSpan.FromSeconds(9)); } } return isRunning; } private static bool IsProcessActive(string processName) { return Process.GetProcessesByName(processName).Any(); }