Creating a Single Instance Application in C#
24. March 2007 11:47
Sometimes, it’s desirable to ensure that there is only ever one instance of your application running at any given time. Take Windows Live Messenger for instance – if you try to launch it whilst it is already running, it will just bring itself to the foreground instead.
Unfortunately, a lot of people try to recreate this behavior by simply checking if a process with the same name is currently running. As K. Scott Allen explains, this is not a good idea. The correct way to implement a single instance application, is to use a named mutex.
The word mutex is short for mutual exclusion, and is a synchronisation object that can only be owned by a single thread at any given time. Specifying a name for the mutex is optional – an unnamed mutex is scoped to the current process, while a named one is associated with an operating system object and can thus be used for interprocess synchronisation. Quite simply then, we can launch our application like this:
bool createdNew = true; using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew)) { if (createdNew) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } }
That ensures that there’s only a single instance of our application running. Now, the above code just ‘does nothing’ if the application is already running – it would be nice if it instead tried to give the main window focus. To do this, we need to find the process instance, and then pinvoke the SetForeGroundWindow method of the Win32 API. Our final Main method then looks like this:
static extern bool SetForegroundWindow(IntPtr hWnd); /// <summary> /// The main entry point for the application. /// </summary> static void Main() { bool createdNew = true; using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew)) { if (createdNew) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } else { Process current = Process.GetCurrentProcess(); foreach (Process process in Process.GetProcessesByName(current.ProcessName)) { if (process.Id != current.Id) { SetForegroundWindow(process.MainWindowHandle); break; } } } } }
On a final note, I would urge you to read Raymond Chen’s excellent post «A single-instance program is it’s own denial of service», which talks about the security implications of implementing single-instance applications.
This post is also available in: English
4/19/2007 2:58:17 PM
Just one addition…see the discussion of protecting your mutex from garbage collection at
http://www.ai.uga.edu/mc/SingleInstance.html
Steve
4/27/2007 3:12:43 PM
In fact, the above solution ensures that the Mutex does not get collected – the using block keeps it in scope until the application exits
Fredrik
9/12/2007 10:00:05 PM
This works only if instance of form isn’t minimized or in system tray…
@Steve, nice solution…
Drunken #BeAvEr#
12/11/2007 11:31:59 AM
Thanks for this great post! It helped me a lot in implementing this behavior.
Still, I have a special case:
Do you know how to bring the app to front when it is hidden (i.e. residing in the system tray only). When hidden the app (or Process) does not have a MainWindowHandle, so I don’t know how to tackle this issue.
Hope you can point me in the right direction.
Thanks & best regards,
matsch
matsch
7/11/2008 2:56:25 AM
When the window is in system tray.
By using
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
And after SetForegroundWindow(process.MainWindowHandle);
//Call to
ShowWindowAsync(process.MainWindowHandle, 9);
Ramki
9/23/2008 3:24:08 PM
What if the your application name is already used by another application??
Mikes
2/5/2009 6:04:11 PM
Dont forget to add
using System.Runtime.InteropServices;
using System.Threading;
and for the 2nd part of the solution (did’nt work me me)
using System.Diagnostics;
luke
2/20/2009 10:58:30 PM
What if the application can accept command line arguments to wire it up?
John Grove
2/23/2009 10:52:36 AM
Trackback from DotNetKicks.com
Creating a Single Instance Application in C#
DotNetKicks.com
2/24/2009 8:09:41 PM
On a related note, here’s an example of how to implement a Single Instance Application using WPF:
pietschsoft.com/post.aspx
Chris Pietschmann
3/3/2009 3:09:20 PM
This has done the trick!
Also thanks to Ramki!!
Biche
3/7/2009 9:48:15 AM
uyiyygdgffdrdtry
ui
4/17/2009 11:13:36 PM
Thanks! This works well. I’m trying to get the first instance to come out of the system tray. I can get it to «restore» out of the taskbar (thanks to Ramki). But how do you get it out of the system tray?
Thanks for any help, Chris