<p>Kind of a special case problem:</p>

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

<p>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).</p>

<p>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 :-(</p>

[{'answer_id': 79174, 'author': 'ageektrapped', 'author_id': 631, 'author_profile': 'https://Stackoverflow.com/users/631', 'pm_score': 1, 'selected': False, 'text': '<p>If you know the window\'s title, you can use the Win32 call, FindWindow, through P/Invoke.</p>\n\n<p>You can find the signature <a href="http://pinvoke.net/default.aspx/user32/FindWindow.html" rel="nofollow noreferrer">here</a> on pinvoke.net</p>\n'}, {'answer_id': 79201, 'author': 'Ash', 'author_id': 5023, 'author_profile': 'https://Stackoverflow.com/users/5023', 'pm_score': 3, 'selected': False, 'text': '<p>@ageektrapped is on the right track, however <code>FindWindow</code> will not search child windows.</p>\n\n<p>For that you will need to use <a href="http://pinvoke.net/default.aspx/user32/FindWindowEx.html" rel="nofollow noreferrer"><code>FindWindowEx</code></a></p>\n'}, {'answer_id': 79205, 'author': 'MB.', 'author_id': 11961, 'author_profile': 'https://Stackoverflow.com/users/11961', 'pm_score': 4, 'selected': True, 'text': '<p>If you don\'t mind using the Windows API, you could use <a href="http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633498.aspx" rel="nofollow noreferrer"><code>EnumWindowsProc</code></a>, and check each of the handles that that turns up using <a href="http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633522.aspx" rel="nofollow noreferrer"><code>GetWindowThreadProcessId</code></a> (to see that it\'s in your process), and then maybe <code>IsWindowVisible</code>, <code>GetWindowCaption</code> and <code>GetWindowTextLength</code> to determine which <code>hWnd</code> in your process is the one you want.</p>\n\n<p>Though if you haven\'t used those functions before that approach will be a real pain, so hopefully there\'s a simpler way.</p>\n'}, {'answer_id': 79277, 'author': 'blackwing', 'author_id': 9107, 'author_profile': 'https://Stackoverflow.com/users/9107', 'pm_score': 1, 'selected': False, 'text': '<p>From what I understand <code>MainWindowHandle</code> property of the process you are starting is not valid. If that\'s the case, you can use <a href="http://msdn.microsoft.com/en-us/library/ms633499.aspx" rel="nofollow noreferrer"><code>FindWindow</code></a> 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 <a href="http://www.windows-spy.com/" rel="nofollow noreferrer">Winspector</a>. You also need to ensure you have the right window by checking that window\'s process id using <a href="http://msdn.microsoft.com/en-us/library/ms633522.aspx" rel="nofollow noreferrer"><code>GetWindowThreadProcessId</code></a>.</p>\n\n<p>At last, I have to say I am not an expert on Win32 and there might be a better solution for your case.</p>\n'}, {'answer_id': 214519, 'author': 'GregUzelac', 'author_id': 27068, 'author_profile': 'https://Stackoverflow.com/users/27068', 'pm_score': 2, 'selected': False, 'text': '<p>You may find that if you call .Refresh() that you get the new top-level window.</p>\n'}, {'answer_id': 247825, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': '<p>Use Process.GetProcessById(proc.Id); where proc was your splash screen.\nWorks for me.</p>\n\n<p>Now, how do you get to main window properties in System.Windows.Forms to give it focus w/o using win32?\nAfter all .net is supposed to be a one-stop solution - is it not?</p>\n'}, {'answer_id': 429793, 'author': 'Marcus Erickson', 'author_id': 38373, 'author_profile': 'https://Stackoverflow.com/users/38373', 'pm_score': 0, 'selected': False, 'text': '<p>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.</p>\n'}, {'answer_id': 429855, 'author': 'Matt Ellis', 'author_id': 29306, 'author_profile': 'https://Stackoverflow.com/users/29306', 'pm_score': 0, 'selected': False, 'text': "<p>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.</p>\n"}, {'answer_id': 4536066, 'author': 'Giova', 'author_id': 554557, 'author_profile': 'https://Stackoverflow.com/users/554557', 'pm_score': 2, 'selected': False, 'text': '<p>Thank you for your answers. Thanks to you here, I figured out how to know if the main window of a process is in front or not:</p>\n\n<p>N.B : of course this needs System.Diagnostic and System.Runtime.Interrop</p>\n\n<pre><code>public bool IsWindowActive(Int32 PID)\n{\n  return IsWindowActive(Process.GetProcessById(PID));\n}\n\n[DllImport("user32.dll")]\nprivate static extern\nIntPtr GetForegroundWindow();\n\npublic bool IsWindowActive(Process proc)\n{\n  proc.Refresh();\n  return proc.MainWindowHandle.Equals(GetForegroundWindow());\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/79111', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/14656/']