2011-07-01 7 views
7

Tengo una aplicación que necesita ejecutar varias otras aplicaciones en cadena. Los estoy ejecutando a través de ShellExecuteEx. El orden de ejecución de cada una de las aplicaciones es muy importante porque dependen el uno del otro. Por ejemplo:Inicie la aplicación externa con ShellExecuteEx y espere hasta que se inicialice

Start(App1); 

If App1.IsRunning then 
    Start(App2); 
If App2.IsRunning then 
    Start(App3); 
......................... 
If App(N-1).IsRunning then 
    Start(App(N)); 

Todo funciona bien, pero no es un posible problema: ShellExecuteEx inicia la aplicación, y regresar casi de inmediato. El problema puede surgir cuando, por ejemplo, App1 ha comenzado correctamente pero no ha terminado algunas tareas internas, todavía no está listo para usar. Pero ShellExecuteEx ya está comenzando App2 que depende de App1, y App2 no se iniciará correctamente porque necesita App1 totalmente inicializado.

Tenga en cuenta, que yo no quiero esperar a que App(N-1) para terminar y luego empezar AppN.

No sé si esto es posible resolver con ShellExecuteEx, he tratado de utilizar

SEInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC; 

pero sin ningún efecto.

Después de iniciar la aplicación AppN tengo un control para el proceso. Si asumo que la aplicación se inicializó después de que se creó su ventana principal (todas las aplicaciones tienen una ventana), ¿puedo poner un gancho en la cola de mensajes y esperar hasta que aparezca WM_CREATE o quizás WM_ACTIVATE? Ante la presencia de dicho mensaje, mi Aplicación sabría que puede seguir adelante.

Es solo una idea. Sin embargo, no sé cómo poner tal gancho. Entonces, si me pueden ayudar en esto o tienen una mejor idea, sería genial :)

Además, la solución debe funcionar en Windows XP y superior.

Gracias por su tiempo.

Editado

@Cosmic Prund: No entiendo por qué se elimina su respuesta? Tal vez intente con tu idea ...

+2

WaitForInputIdle (hProcess ... –

Respuesta

12

Probablemente puedas lograr lo que necesitas si llamas al WaitForInputIdle() en cada manija de proceso devuelta por ShellExecute().

Espera hasta que el proceso especificado haya terminado de procesar su entrada inicial y está esperando la entrada del usuario sin entrada pendiente, o hasta que haya transcurrido el intervalo de tiempo de espera.

+0

David: Esto suena bien para ser cierto;) ¿Pero qué significa en realidad que "el proceso especificado ha terminado su inicialización"? – Wodzu

+0

+1, agradable y simple. @Wodzu, acaba de hacer una aplicación simple con un bucle tonto de 10 segundos en 'FormCreate',' WaitForInputIdle() 'regresó tan pronto como terminó el ciclo (y se muestra el formulario principal). –

+0

Gracias @Cosmin, de todos modos es una pena que hayas borrado tu respuesta. Yo quería otorgarlo también :) – Wodzu

3

Si su aplicación tiene alguna lógica de inicialización personalizada que no se ejecuta en el subproceso de interfaz de usuario, WaitForInputIdle podría no ser de ayuda. En ese caso, necesita un mecanismo para indicar a la aplicación anterior que ya terminó de inicializar.

Para la señalización puede utilizar canalizaciones con nombre, sockets, algún mecanismo RPC o un simple bloqueo basado en archivo.

+0

Gracias Hasan, pero he dicho y definido lo que quiero decir con la inicialización, una cita mía "Supongo que la aplicación se inicializa después de que se creó su ventana principal (todas las aplicaciones tienen una ventana)" – Wodzu

+0

Entonces WaitForInputIdle es todo lo que necesitar. –

0

Siempre puede usar IPC y Interpocess Synchronization para hacer que su aplicación se comunique (y espere, si es necesario) entre sí, siempre que codifique ambas aplicaciones.

Cuestiones relacionadas