tags:

views:

2879

answers:

15

In .NET, what's the best way to prevent multiple instances of an app from running at the same time? And if there's no "best" technique, what are some of the caveats to consider with each solution?

+3  A: 

http://en.csharp-online.net/Application_Architecture_in_Windows_Forms_2.0—Single-Instance_Detection_and_Management

aaronjensen
+2  A: 

This article simply explains how you can create a windows application with control on the number of its instances or run only single instance. This is very typical need of a business application. There are already lots of other possible solutions to control this.

http://www.openwinforms.com/single_instance_application.html

smink
+6  A: 

Hanselman has a post on using the WinFormsApplicationBase class from the Microsoft.VisualBasic assembly to do this.

bdukes
I've been using that for a couple years, but am now looking to change to a Mutex-based solution. I have customers that report issues with this and I suspect it's using Remoting to do it.
Richard Watson
A: 

You have to use System.Diagnostics.Process.

Check out: http://www.devx.com/tips/Tip/20044

Thomas Jespersen
A: 

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.

Tomer Gabel
A: 

i've used this before

http://www.bobpowell.net/singleinstance.htm

for using a single instance application and showing the application if a user try to make another instance.

Hath
+1  A: 
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;
}
Thomas Wagner
+5  A: 

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.

Doliveras
I looked for this checkbox you mention, for my C#/WPF app, and there isn't any.
HappyNomad
I don't see it in my VS 2008 C#/WinForms app's properties either.
Jesse McGrew
+15  A: 

Use Mutex. One of the examples above using GetProcessByName has many caveats. Here is a good article on the subject:

http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

[STAThread]
static void Main() 
{
   using(Mutex mutex = new Mutex(false, "Global\\" + appGuid))
   {
      if(!mutex.WaitOne(0, false))
      {
         MessageBox.Show("Instance already running");
         return;
      }

      GC.Collect();                
      Application.Run(new Form1());
   }
}
ImJustPondering
Using a mutex also works for non .net code as well (although the syntax would vary)
crashmstr
This code should handle agandonedmutexexceptions
Sam Saffron
Here's a slightly more filled-out version, with some good comments:http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567
Richard Watson
+2  A: 

It sounds like there are 3 fundamental techniques that have been suggested so far.

  1. 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?)
  2. Use a named mutex and check if it's already been created.
  3. 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?

C. Dragon 76
I don't think 3 is very efficient. I'd vote for the Mutex, used it without problems many times. I've never used item 1 not sure how that flies when you're in c#.
typemismatch
Option 1 still works with WPF it's just slightly more involved.http://msdn.microsoft.com/en-us/library/ms771662.aspx
Graeme Bradbury
How does 2 work with multilpe users on a terminal server?
SillyMonkey
application services do not work in safe mode
Sam Saffron
it works fine with WPF apps.
moogs
+1  A: 

Here 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!
            System.Exit(1);
        }
    }
}
Terrapin
A: 

Use VB.NET! No: really ;)

using Microsoft.VisualBasic.ApplicationServices;

The WindowsFormsApplicationBase from VB.Net provides you with a "SingleInstace" Property, which determines other Instances and let only one Instance run.

MADMap
A: 

Hi,

[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

Ric Tokyo
A: 

Hi,

Thomas wagner... thanks for your post.. its work fine...... once again thanks