2010-11-05 4 views
7

Esto debería ser fácil: estoy creando un programa que engendra un proceso usando la función win32 CreateProcess(). Una vez que se carga este proceso, encuentro su ventana usando FindWindow y le envío mensajes usando SendMessage(). La pregunta es: ¿cómo sé cuándo esa ventana está lista para aceptar mensajes?¿Cómo determinar cuándo está listo el proceso generado? (Usando CreateProcess() y FindWindow())

considerar lo siguiente:

HWND wnd; 

BOOL Start() 
{ 
    // Spawn the process 
    if (! CreateProcess(...)) 
    return FALSE; 

    // Find the process's window (class and name already known) 
    wnd = FindWindow(MY_WINDOW_CLASS, MY_WINDOW_NAME); 

    // Always returns FALSE because window has not yet been created. 
    return (wnd != NULL); 
} 

El código anterior (? Casi) siempre fallar; la ventana no se puede crear y se encuentra tan rápido. Si puse un hilo en espera, digamos Sleep(1000), entre las llamadas CreateProcess y FindWindow, funciona bien. Pero esto se siente como un muy bad hack.

¿Cómo puedo mejorar esto?

Respuesta

9

(Editar): User IInspectable señaló problemas con WaitForInputIdle(), y sugirió CBT Hooks en su lugar.

(...) función de devolución de llamada utilizada con la función SetWindowsHookEx . El sistema llama a esta función antes de activar, creando, (...) una ventana; (... muchas otras cosas).

Además, la TCC es la abreviatura de formación asistida por ordenador, por cualquier razón.

(Viejo, tenga cuidado, vea los comentarios.) Usted busca WaitForInputIdle(). Cita:

Cuando un proceso padre crea un proceso hijo , la función CreateProcess devoluciones sin esperar a que el proceso hijo para terminar su inicialización. Antes de intentar comunicarse con el proceso hijo , el proceso principal puede usar la función WaitForInputIdle para determinar cuándo se ha completado la inicialización del niño .

+0

Perfecto. ¡Gracias! –

+2

La API de Windows es tan grande que nadie puede esperar saberlo todo.Aprendí algo nuevo hoy, gracias. –

+1

Este es un error que está por ocurrir. 'WaitForInputIdle' se inventó para abordar los requisitos de DDE. Usarlo para cualquier otra cosa va a fallar, de la manera más sutil. Lectura relevante: [WaitForInputIdle realmente debería llamarse WaitForProcessStartupComplete] (https://blogs.msdn.microsoft.com/oldnewthing/20100325-00/?p=14493) y [WaitForInputIdle espera por cualquier hilo, que podría no ser el hilo que usted se preocupe por] (https://blogs.msdn.microsoft.com/oldnewthing/20100326-00/?p=14483). – IInspectable

1

Si el proceso que está iniciando es uno que puede cambiar, hágalo enviar un mensaje al padre cuando esté listo. Puede pasar el HWND del padre como un parámetro de línea de comando, o usar FindWindow si puede garantizar que el padre será único.

1

Supongo que el código fuente de ambos procesos está bajo su control.

  • Puede dejar que el segundo proceso publique un mensaje al primero cuando esté listo, si el segundo conoce los detalles necesarios de la ventana del mensaje del primer proceso.
  • O puede esperar en el primer proceso para un objeto de sincronización nombrado previamente acordado, como evento o mutex, que se establece desde el segundo proceso.
Cuestiones relacionadas