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?
Re: SetForeGroundWindow:
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.
Same as OP, I found that
SetForegroundWindow
alone wasn't enough when the window was minimized. Since I didn't want to useSwitchToThisWindow
, I choseShowWindow
followed bySetForegroundWindow
.Works well for me!
I believe you will want to use SetForegroundWindow
MSDN Example
Can you grab MainWindowHandle property of the Process object and send it a WM_USER message that you can interpret as "some other instance wants to bring me to the front".
Complete Side Note...
You can use
instead of looping over all the processes running on the system...
UPDATE
PInvoke Rules for this sort of thing...
C# equivalent of Tom Juergens's answer. Works like a charm for me.