There can be only one!

I had to make a slight change to one of my applications for a customer today, making it check if it is already running on the local machine and, if it is, abandon it’s attempt to start up another instance.

My initial thoughts were to examine the executing processes and check for the existence of the application in the list:

1
2
3
4
5
6
7
8
    string procName = Process.GetCurrentProcess().ProcessName;           
    Process[] processes= Process.GetProcessesByName(procName);
 
    if (processes.Length == 1)
    {
        //run application
        ...
    }

Now, whilst this works, it is easily “beatable” by simply changing the executable’s name. Doing so will cause the method “GetProcessessByName()” to return only a single match, instead of the current application and any other duplicate instances.

After pondering on the subject for a while, I started to think how threading works, or more precisely, how threading deals with shared resources.

When a thread attempts to access a shared resource, an exclusive lock is applied to that resource until the thread completes it’s task. These locks are actually “Mutex” objects (read more here).

Using a Mutex, I was able to create the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
    bool isFirstInstance;
    Mutex mx = new Mutex(true,"Global\\MyApplicationName",out isFirstInstance);
 
    if (isFirstInstance)
    {
        //run application
        ...
        mx.Close();
    }
    else
    {
        //application already running
    }

The “Global\\” prefix tells the Mutex to be available across all user instances on the machine, not just the current.

Also, whilst it’s not strictly required to close the Mutex before exiting, as it will be automatically closed when the application ends, I’ve added it in this example for completeness.

In my opinion, this method is more reliable, more robust, and slightly cooler ;)


Leave a Reply