In this short code snippet, I want to show a simple technique for ensuring only one instance of your .NET application can run at a time.

The technique is below :

    using System.Threading;
    using System.Windows;

    namespace MyApplication
    {
	    public partial class App : Application
	    {
	        private Mutex _mutex;

	        public App()
	        {
	            bool aIsNewInstance;

	            _mutex = new Mutex(true, @"Global\" + "MyUniqueWPFApplicationName", out aIsNewInstance);

	            GC.KeepAlive(_mutex);

	            if (aIsNewInstance) return;

	            MessageBox.Show("There is already an instance running.",
	                "Instance already running.",
	                MessageBoxButton.OK, MessageBoxImage.Information);

	            Current.Shutdown();
	        }
	    }
    }

What happens is that a Mutex is created when the application starts up and it is given a unique name, in this case, “MyUniqueWPFApplicationName“. If another instance of the application is started up and the Mutex is already created with that name, the application will shut down. You will also notice that there is a prefix to the name (Global\) that makes the unique name global to a sever running terminal services. If you leave off this prefix, then the mutex is considered local.

There is a a good description of this on the MSDN page for Mutex.

On a server that is running Terminal Services, a named system mutex can have two levels of visibility. If its name begins with the prefix “Global\”, the mutex is visible in all terminal server sessions. If its name begins with the prefix “Local\”, the mutex is visible only in the terminal server session where it was created. In that case, a separate mutex with the same name can exist in each of the other terminal server sessions on the server. If you do not specify a prefix when you create a named mutex, it takes the prefix “Local\”. Within a terminal server session, two mutexes whose names differ only by their prefixes are separate mutexes, and both are visible to all processes in the terminal server session. That is, the prefix names “Global\” and “Local\” describe the scope of the mutex name relative to terminal server sessions, not relative to processes.

The GC.KeepAlive(_mutex) is needed because we want the program to keep hold of the mutex as long as it’s running. But the JIT compiler sees that the mutex is only used near the beginning of the program, and may discard it prematurely when memory is needed for something else.

Another common implementation of forcing a single instance is to check for a running process name for another process with the same name. This works by using the Process class from the System.Diagnostics namespace. You would call Process.GetProcessesByName(processName) to see if there are any existing processes running with the same name, and exit the application if another process is found.

There are a number of problems with this option like :

  1. Two instances of the application could launch at almost the same time, see each other, and close down (race condition).
  2. This doesn’t work in terminal services if you want an instance to run in each login session.
  3. You could possibly have another process running on the system with the same name.

As you can see, the Process.GetProcessesByName name will work if the above risks are acceptable to you, but I recommend using the Mutex option instead.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s