Veiledning - Spørsmål

CreatingaSingleInstanceApplicationinC.aspx

Creating a Single Instance Application in C#

An entry about c# 3.0 | windows forms Publication date 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.

 

4/19/2007 2:58:17 PM

Steve

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

Fredrik

In fact, the above solution ensures that the Mutex does not get collected – the using block keeps it in scope until the application exits Smile

Fredrik

9/12/2007 10:00:05 PM

Drunken #BeAvEr#

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

matsch

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

Ramki

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

Mikes

What if the your application name is already used by another application??

Mikes United States

2/5/2009 6:04:11 PM

luke

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 United Kingdom

2/20/2009 10:58:30 PM

John Grove

What if the application can accept command line arguments to wire it up?

John Grove United States

2/23/2009 10:52:36 AM

trackback

Trackback from DotNetKicks.com

Creating a Single Instance Application in C#

DotNetKicks.com

2/24/2009 8:09:41 PM

Chris Pietschmann

On a related note, here’s an example of how to implement a Single Instance Application using WPF:
pietschsoft.com/post.aspx

Chris Pietschmann United States

3/3/2009 3:09:20 PM

Biche

This has done the trick!

Also thanks to Ramki!!

Biche Canada

3/7/2009 9:48:15 AM

ui

uyiyygdgffdrdtry

ui Argentina

4/17/2009 11:13:36 PM

Chris

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

This post is also available in: English

author-avatar

About Aksel Lian

En selvstendig full stack webutvikler med en bred variasjon av kunnskaper herunder SEO, CMS, Webfotografi, Webutvikling inkl. kodespråk..

One thought on “CreatingaSingleInstanceApplicationinC.aspx

  1. Tilbaketråkk: My Homepage

Comments are closed.