How do you get a Process' main window handle in C#?

John Smith picture John Smith · Jun 3, 2012 · Viewed 13.5k times · Source

The objective is to programmatically start a Windows Form, get its handle, and send info to its wndProc() function using Win Api's SendMessage() function.

I got the SendMessage() part taken care of but the problem now is getting the form's handle after the process has been started.

My first guess was that Process' MainWindowHandle property would get me the handle I am looking for, but after I start the process MainWindowHandle remains equal to 0 and the following code doesn't show the handle of the process I just started:

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

Can someone tell me how to do this and whether it can actually be done?

Answer

SimpleVar picture SimpleVar · Jun 3, 2012

Sometimes the Process takes a second the set up everything, but the object is returned immediately.

For that reason, you should wait a little bit, in order to let the Process really get it started, and then it's MainWindowHandle will be set appropriately, ready to be consumed.

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

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

var handle = proc.MainWindowHandle;

Another way to do it in a more smart fashion would be:

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
}

That will cause the process to start, and wait until the MainWindowHandle isn't empty.