In .NET, how can I prevent multiple instances of an app from running at the same time and what caveats should I consider if there are multiple ways to do it?
19 Answers
Use Mutex. One of the examples above using GetProcessByName has many caveats. Here is a good article on the subject:
[STAThread]
static void Main()
{
using(Mutex mutex = new Mutex(false, "Global\\" + appGuid))
{
if(!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}
Application.Run(new Form1());
}
}
private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9";
13 Comments
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value; which will get the executing assembly's guidHere is the code you need to ensure that only one instance is running. This is the method of using a named mutex.
public class Program
{
static System.Threading.Mutex singleton = new Mutex(true, "My App Name");
static void Main(string[] args)
{
if (!singleton.WaitOne(TimeSpan.Zero, true))
{
//there is already another instance running!
Application.Exit();
}
}
}
3 Comments
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
{
AppLog.Write("Application XXXX already running. Only one instance of this application is allowed", AppLog.LogMessageType.Warn);
return;
}
5 Comments
1 - Create a reference in program.cs ->
using System.Diagnostics;
2 - Put into void Main() as the first line of code ->
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length >1)
return;
That's it.
2 Comments
Mutex? Is there a catch?After trying multiple solutions i the question. I ended up using the example for WPF here: http://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/
public partial class App : Application
{
private static Mutex _mutex = null;
protected override void OnStartup(StartupEventArgs e)
{
const string appName = "MyAppName";
bool createdNew;
_mutex = new Mutex(true, appName, out createdNew);
if (!createdNew)
{
//app is already running! Exiting the application
Application.Current.Shutdown();
}
}
}
In App.xaml:
x:Class="*YourNameSpace*.App"
StartupUri="MainWindow.xaml"
Startup="App_Startup"
Comments
It sounds like there are 3 fundamental techniques that have been suggested so far.
- Derive from the Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase class and set the IsSingleInstance property to true. (I believe a caveat here is that this won't work with WPF applications, will it?)
- Use a named mutex and check if it's already been created.
- Get a list of running processes and compare the names of the processes. (This has the caveat of requiring your process name to be unique relative to any other processes running on a given user's machine.)
Any caveats I've missed?
2 Comments
i tried all the solutions here and nothing worked in my C# .net 4.0 project. Hoping to help someone here the solution that worked for me:
As main class variables:
private static string appGuid = "WRITE AN UNIQUE GUID HERE";
private static Mutex mutex;
When you need to check if app is already running:
bool mutexCreated;
mutex = new Mutex(true, "Global\\" + appGuid, out mutexCreated);
if (mutexCreated)
mutex.ReleaseMutex();
if (!mutexCreated)
{
//App is already running, close this!
Environment.Exit(0); //i used this because its a console app
}
I needed to close other istances only with some conditions, this worked well for my purpose
1 Comment
Using Visual Studio 2005 or 2008, when you create a project for an executable, on the properties windows inside the "Application" panel, there is a check box named “Make single instance application” that you can activate to convert the application on a single instance application.
Here is a capture of the window I'm talking of:

This is a Visual Studio 2008 windows application project.
6 Comments
This is the code for VB.Net
Private Shared Sub Main()
Using mutex As New Mutex(False, appGuid)
If Not mutex.WaitOne(0, False) Then
MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
Application.Run(New Form1())
End Using
End Sub
This is the code for C#
private static void Main()
{
using (Mutex mutex = new Mutex(false, appGuid)) {
if (!mutex.WaitOne(0, false)) {
MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Application.Run(new Form1());
}
}
Comments
[STAThread]
static void Main() // args are OK here, of course
{
bool ok;
m = new System.Threading.Mutex(true, "YourNameHere", out ok);
if (! ok)
{
MessageBox.Show("Another instance is already running.");
return;
}
Application.Run(new Form1()); // or whatever was there
GC.KeepAlive(m); // important!
}
From: Ensuring a single instance of .NET Application
and: Single Instance Application Mutex
Same answer as @Smink and @Imjustpondering with a twist:
Jon Skeet's FAQ on C# to find out why GC.KeepAlive matters
You have to use System.Diagnostics.Process.
Check out: http://www.devx.com/tips/Tip/20044
Comments
(Note: this is a fun-solution! It works but uses bad GDI+ design to achieve this.)
Put an image in with your app and load it on startup. Hold it until the app exits. The user wont be able to start a 2nd instance. (Of course the mutex solution is much cleaner)
private static Bitmap randomName = new Bitmap("my_image.jpg");
4 Comments
Main() method which goes against how WPF is supposed to work.Normally it's done with a named Mutex (use new Mutex( "your app name", true ) and check the return value), but there's also some support classes in Microsoft.VisualBasic.dll that can do it for you.
Comments
This worked for me in pure C#. the try/catch is when possibly a process in the list exits during your loop.
using System.Diagnostics;
....
[STAThread]
static void Main()
{
...
int procCount = 0;
foreach (Process pp in Process.GetProcesses())
{
try
{
if (String.Compare(pp.MainModule.FileName, Application.ExecutablePath, true) == 0)
{
procCount++;
if(procCount > 1) {
Application.Exit();
return;
}
}
}
catch { }
}
Application.Run(new Form1());
}
Comments
Be sure to consider security when restricting an application to a single instance:
Full article: https://blogs.msdn.microsoft.com/oldnewthing/20060620-13/?p=30813
We are using a named mutex with a fixed name in order to detect whether another copy of the program is running. But that also means an attacker can create the mutex first, thereby preventing our program from running at all! How can I prevent this type of denial of service attack?
...
If the attacker is running in the same security context as your program is (or would be) running in, then there is nothing you can do. Whatever "secret handshake" you come up with to determine whether another copy of your program is running, the attacker can mimic it. Since it is running in the correct security context, it can do anything that the "real" program can do.
...
Clearly you can't protect yourself from an attacker running at the same security privilege, but you can still protect yourself against unprivileged attackers running at other security privileges.
Try setting a DACL on your mutex, here's the .NET way: https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.mutexsecurity(v=vs.110).aspx
Comments
None of this answers worked for me because I needed this to work under Linux using monodevelop. This works great for me:
Call this method passing it a unique ID
public static void PreventMultipleInstance(string applicationId)
{
// Under Windows this is:
// C:\Users\SomeUser\AppData\Local\Temp\
// Linux this is:
// /tmp/
var temporaryDirectory = Path.GetTempPath();
// Application ID (Make sure this guid is different accross your different applications!
var applicationGuid = applicationId + ".process-lock";
// file that will serve as our lock
var fileFulePath = Path.Combine(temporaryDirectory, applicationGuid);
try
{
// Prevents other processes from reading from or writing to this file
var _InstanceLock = new FileStream(fileFulePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
_InstanceLock.Lock(0, 0);
MonoApp.Logger.LogToDisk(LogType.Notification, "04ZH-EQP0", "Aquired Lock", fileFulePath);
// todo investigate why we need a reference to file stream. Without this GC releases the lock!
System.Timers.Timer t = new System.Timers.Timer()
{
Interval = 500000,
Enabled = true,
};
t.Elapsed += (a, b) =>
{
try
{
_InstanceLock.Lock(0, 0);
}
catch
{
MonoApp.Logger.Log(LogType.Error, "AOI7-QMCT", "Unable to lock file");
}
};
t.Start();
}
catch
{
// Terminate application because another instance with this ID is running
Environment.Exit(102534);
}
}
Comments
For a WPF application built in Prism framework , I have used the same code of @ImJustPondering in this manner. First go to App.xaml.cs and use it in this way.
public partial class App
{
static System.Threading.Mutex singleton = new Mutex(true, "DicomViewerApplication");
protected override Window CreateShell()
{
if (!singleton.WaitOne(TimeSpan.Zero, true))
{
Current.Shutdown();
}
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IMessageService, MessageService>();
containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
moduleCatalog.AddModule<ModuleNameModule>();
}
}
So before container is resolving Shell (MainWindow.xaml) we need to exit application in this way if another instance is already running.