2012-06-03 17 views
8

El objetivo es iniciar programáticamente Windows Form, obtener su identificador y enviar información a su función wndProc() utilizando la función SendMessage() de Win Api.¿Cómo se obtiene el identificador de una ventana principal de Process en C#?

Recibí la parte SendMessage() pero el problema ahora es obtener el identificador del formulario después de que se haya iniciado el proceso.

Mi primera suposición fue que la propiedad MainWindowHandle de Process me daría el control que estoy buscando, pero después de iniciar el proceso MainWindowHandle sigue siendo igual a 0 y el siguiente código no muestra el manejo del proceso que acabo de iniciar :

foreach (Process p in Process.GetProcesses()) 
{ 
Console.WriteLine(p.MainWindowHandle); 
} 

¿Alguien me puede decir cómo hacerlo y si realmente se puede hacer?

+2

Intenta hacer 'Thread.Sleep (3000);' después de comenzar el proceso, mira si el resultado es diferente. Además, ¿qué proceso estás comenzando? ¿Tiene incluso una ventana? – SimpleVar

+0

parece que poner el hilo a dormir hizo el truco. gracias –

+0

@YoryeNathan ¿puedes poner tu comentario como la respuesta? –

Respuesta

9

A veces, el proceso tarda un segundo en configurar todo, pero el objeto se devuelve inmediatamente.

Por esta razón, debe esperar un poco, para que el proceso realmente comience, y luego MainWindowHandle se configurará adecuadamente, listo para ser consumido.

var proc = Process.Start("notepad"); 

Thread.Sleep(1000); // This will wait 1 second 

var handle = proc.MainWindowHandle; 

Otra manera de hacerlo de una manera más inteligente sería:

var proc = Process.Start("notepad"); 

try 
{ 
    while (proc.MainWindowHandle == IntPtr.Zero) 
    { 
     // Discard cached information about the process 
     // because MainWindowHandle might be cached. 
     proc.Refresh(); 

     Thread.Sleep(10); 
    } 

    var handle = proc.MainWindowHandle; 
} 
catch 
{ 
    // The process has probably exited, 
    // so accessing MainWindowHandle threw an exception 
} 

que hará que el proceso para iniciar, y esperar hasta que el MainWindowHandle no está vacío.

+0

en realidad Yorye, creo que sería negligente si no menciono que en base a mis observaciones, su segundo enfoque no va a funcionar, porque, por alguna razón, si accede a MainWindowHandle antes de que se haya inicializado, no lo hace Iníciese en absoluto, lo que significa que su ciclo while se ejecutará para siempre. ¿Por qué es así? No lo sé, pero pruébalo si no me crees. –

+3

@JohnSmith Tienes razón, la información se almacena en caché en el objeto. Llamar al método 'Refresh' descarta esa información en caché, por lo que la próxima vez que acceda a la propiedad' MainWindowHandle', la recuperará de la ventana real, según sea necesario. Ver la actualización de mi publicación. – SimpleVar

+0

A veces estoy aprendiendo cosas nuevas de mis propias respuestas hace 3 años. – SimpleVar

Cuestiones relacionadas