tags:

views:

8885

answers:

9

Kind of a special case problem:

  • I start a process with System.Diagnostics.Process.Start(..)
  • The process opens a splash screen -- this splash screen becomes the main window.
  • The splash screen closes and the 'real' UI is shown. The main window (splash screen) is now invalid.
  • I still have the Process object, and I can query its handle, module, etc. But the main window handle is now invalid.

I need to get the process's UI (or UI handle) at this point. Assume I cannot change the behavior of the process to make this any easier (or saner).

I have looked around online but I'll admit I didn't look for more than an hour. Seemed like it should be somewhat trivial :-(

Thanks

+1  A: 

If you know the window's title, you can use the Win32 call, FindWindow, through P/Invoke.

You can find the signature here on pinvoke.net

ageektrapped
+5  A: 

@ageektrapped is on the right track, however FindWindow will not search child windows.

For that you will need to use FindWindowEx

Ash
+4  A: 

If you don't mind using the Windows API, you could use EnumWindowsProc, and check each of the handles that that turns up using GetWindowThreadProcessId (to see that it's in your process), and then maybe IsWindowVisible, GetWindowCaption and GetWindowTextLength to determine which hWnd in your process is the one you want.

Though if you haven't used those functions before that approach will be a right pain, so hopefully there's a simpler way.

MB
I have found that this is a much more robust solution than FindWindowEx, even though it is harder to set up. FindWindowEx will struggle when you have multiple instances of the target application running.
Zooba
+1  A: 

From what I understand MainWindowHandle property of the process you are starting is not valid. If that's the case, you can use FindWindow function (from Win32 SDK) which returns the window handle you need. All you need is the class name of target application's main window. You can obtain it using Spy++ or Winspector. You also need to ensure you have the right window by checking that window's process id using GetWindowThreadProcessId.

At last, I have to say I am not an expert on Win32 and there might be a better solution for your case.

blackwing
A: 

For some great examples, you should have a look at http://mwinapi.sourceforge.net/.

Sebastien Lachance
A: 

You may find that if you call .Refresh() that you get the new top-level window.

GregUzelac
A: 

Use Process.GetProcessById(proc.Id); where proc was your splash screen. Works for me.

Now, how do you get to main window properties in System.Windows.Forms to give it focus w/o using win32? After all .net is supposed to be a one-stop solution - is it not?

A: 

Somewhere in the code, the "real" main window is created. You can just save the window handle at that time and then after the splash screen closes you can set Application.MainWindow to the real window.

Marcus Erickson
A: 

The MainWindowHandle property is cached after it is first accessed which is why you don't see it changing even after the handle becomes invalid. GregUzelac's information is correct. Calling Proces.Refresh will causes the next call to Process.MainWindowHandle to re-do the logic to find a new main window handle. Michael's logic also works because the new Process doesn't have a cached version of the MainWindowHandle.

Matt Ellis