C# - Single Application Instance

Sometimes you need to make sure that there is only one copy of your application running at a time.  There a few different ways to accomplish this task, I will go over two that I think are very safe. Lets start off by creating a simple Windows application.

Using a mutex

The most common approach is using a mutex.  A mutex is short for mutual exclusion and is a simple data structure used for concurrent programming.  In .Net, the Mutex object is a Windows Kernel Object used as a locking mechanism across AppDomains and Processes. 

Let's create a class called SingleInstance and import the System.Threading namespace.  Inside the class, place a boolean firstInstance variable and an associated property.  This will represent if the application failed to be the first instance.

        private bool firstInstance = false;

        //If returns true, the application already exists
        public bool FirstInstance
        {
            get { return firstInstance; }
        }

In the Program.cs file we will modify the Main method as follows:

        [STAThread]
        static void Main()
        {
            SingleInstance single = new SingleInstance();

            if (single.FirstInstance)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
            else
            {
                MessageBox.Show("SingleInstanceApp is already running");
            }
            
        }

Then when the second instance is run our goal is to get

image

Next put the following code in the default constructor of the SingleInstance class:

        private void SingleInstance
        {
            try
            {
                //Grab mutex if it exists
                mutex = Mutex.OpenExisting("SingleInstanceApp");
            }
            catch (WaitHandleCannotBeOpenedException e)
            {
                //The mutex doesn't exist
                firstInstance = true;
            }

            //Create mutex if still null
            if (mutex == null)
            {
                mutex = new Mutex(false, "SingleInstanceApp");
                
                //Keep Garbage Collection away
                GC.KeepAlive(mutex);
            }
        }

First, we check if there is a current mutex with the name "SingleInstanceApp".  This is a unique name you must pick to represent your application.  You can add "Local\\" in front of the name to allow different users of the same system run their own instance.  If left out, the mutex is check across all processes/AppDomains of the system.  If no mutex with that name exists, a WaitHangleCannotBeOpendException is thrown.  Then we check to see if the mutex exists by comparing to null and if needed we create the new mutex.

Finally be need to keep the mutex a live in memory while the application is running.  The Garbage collection is smart enough to determine that the SingleInstance class is never referenced again, therefore destroying it.  The GC.KeepAlive(Object obj) method keeps the object in memory until the AppDomain is unloaded.

There is also another approach using a mutex.  Create two methods with a return type of void, Mutex1() and Mutex2().  Put the current code in the constructor in Mutex1().  Next copy the code for the Constructor and Mutex2().

        public SingleInstance()
        {
            Mutex2();
        }

        private void Mutex2()
        {
            //get Mutex
            Mutex mutex = new Mutex(false, "SingleInstanceApp", out firstInstance);

            if (firstInstance)
                GC.KeepAlive(mutex);
        }

This overloaded method will get the current mutex if it exists or create one.  The output boolean variable is true if the mutex did not previously exist.

Process Lookup

Another way to enforce a single instance is by doing a simple process lookup.  Import the System.Diagnostics namespace.  Then change the constructor and add the following method ProcessLookup():

        public SingleInstance()
        {
            ProcessLookup();
        }

        private void ProcessLookup()
        {
            //Get current process
            Process current = Process.GetCurrentProcess();

            //Get array or processes with same name
            Process[] procs = Process.GetProcessesByName(current.ProcessName);

            //Check count
            if (procs.Length == 1)
                firstInstance = true;
        }

I think this method is much slower than the previous method, but it also works fine.  This also adds the issue of tricking the application and running multiple copies by simply renaming the executable.

You could further extend and instead of displaying a message or closing the Application, bring the current window to focus.  Unfortunately, I do not think there is an easy way to do this without using the user32.dll from the windows32 library.  Code for doing this can be found at this article on CodeProject.

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Posted by: kjsteuer
Posted on: 4/16/2008 at 11:32 AM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (7) | Post RSSRSS comment feed

Comments

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading