Full repro example (.NET Framework 4.8 Console application, Windows 10):
using System.Diagnostics;
using System.Windows.Forms;
static class Program
{
static void Main()
{
var p = Process.Start("explorer.exe", @"C:\Windows");
p.WaitForInputIdle();
// Thread.Sleep(5000);
MessageBox.Show("Explorer window has opened.");
}
}
Actual behavior: The message box shows up. A few seconds later, the Explorer window opens in front of the message box, thereby hiding the message.
Desired behavior: The code waits until the Explorer window is visible (that's what I expected WaitForInputIdle
to do) and then shows the message box in front of the Explorer window.
What I've already tried:
- If I activate the
Thread.Sleep
statement in my code example, it works (i.e., I get the desired behavior). I don't like that solution, because the time it takes to open the Explorer window might be different on my computer and on my customers' computers. - I tried various combinations of the various
ProcessStartInfo
options (UseShellExecute
,WindowStyle
,CreateNoWindow
), but it did not make a difference. Note that I don't want to hide the Explorer window, I just want to wait until it's visible. - I know that I can use
SetForegroundWindow
to make my process the foremost window. That doesn't help. It's (a) apparently not necessary (the Thread-Sleep-variant works without it) and (b) I'd need to do it after the Explorer window finished opening to prevent the Explorer window from "stealing" the foreground again, leading back to my original problem. - I also tried checking
p.MainWindowTitle
in a loop, but that value stays empty even after the window has opened (or the process exits). Apparently, the new Explorer window is actually owned by a different process than the one I started. - I know that I could use the Windows API methods
FindWindow
orEnumWindows
to find out if any window with the name of the folder exists, but that's (a) a lot of work and (b) not very elegant.
Did I miss an obvious, correct solution to this?