Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 788
John Smith Avatar asked Jun 03 '12 02:06

John Smith


People also ask

What is main window handle?

The MainWindowHandle property is a value that uniquely identifies the window that is associated with the process. A process has a main window associated with it only if the process has a graphical interface. If the associated process does not have a main window, the MainWindowHandle value is zero.

How do I get Hwnd from process handle?

You can use EnumWindows and GetWindowThreadProcessId() functions as mentioned in this MSDN article.

What is window handle in C#?

Once the Selenium WebDriver instance is instantiated, a unique alphanumeric id is assigned to the window. This is called window handle and is used to identify browser windows.


1 Answers

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.

like image 124
SimpleVar Avatar answered Oct 26 '22 15:10

SimpleVar