I have an application which may only have one instance of itself open at a time. To enforce this, I use this code:
System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcesses(); System.Diagnostics.Process me = System.Diagnostics.Process.GetCurrentProcess(); foreach (System.Diagnostics.Process p in myProcesses) { if (p.ProcessName == me.ProcessName) if (p.Id != me.Id) { //if already running, abort this copy. return; } } //launch the application. //...
It works fine. I would also like it to be able to focus the form of the already-running copy. That is, before returning, I want to bring the other instance of this application into the foreground.
How do I do that?
SetForegroundWindow works, to a point:
[System.Runtime.InteropServices.DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); // ... if (p.Id != me.Id) { //if already running, focus it, and then abort this copy. SetForegroundWindow(p.MainWindowHandle); return; } // ...
This does bring the window to the foreground if it is not minimized. Awesome. If the window IS minimized, however, it remains minimized.
It needs to un-minimize.
Solution via SwitchToThisWindow (Works!):
[System.Runtime.InteropServices.DllImport("user32.dll")] public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); [STAThread] static void Main() { System.Diagnostics.Process me = System.Diagnostics.Process.GetCurrentProcess(); System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcessesByName(me.ProcessName); foreach (System.Diagnostics.Process p in myProcesses) { if (p.Id != me.Id) { SwitchToThisWindow(p.MainWindowHandle, true); return; } } //now go ahead and start our application ;-) }
I had the same problem and SwitchToThisWindow() worked the best for me. The only limitation is that you must have XP sp1 installed. I played with SetForegroundWindow, ShowWindow, and they both had problems pulling the window into view.