Software and entrepreneurship

Software and entrepreneurship

Single instance Windows applications in C#

Motivation

There is often the need to create programs for Windows that should be started only once.

Following the DRY principle repetitive code should be extracted (for example in a static helper class).

After that, all that is left to do, is wrap the core application logic in this code.

Please note, that this article does not implement and discuss the Singleton Pattern. If you are looking for implementation of the singleton pattern in C# look at Jon Skeet's excellent article.

Implementation

Mutex - a system-wide unique name

The helper utility in this article is implemented as a static class with one static method.

The class uses a named Mutex to flag system-wide, that the application is already running.

Mutex is an abbreviation of [mutual exclusion](en.wikipedia.org/wiki/Mutual_exclusion) - term used usually in a context of threading, where using mutexes is an option to prevent race conditions, when multiple threads need to access the same data.

This pattern works as expected, only if the name of the mutex object is unique - no other mutex on the system, on which the application should run, has the same name.

Example of a unique mutex name is:

_ApplicationName_GUID_

If the application name is ServicesControllerUtility and a GUID is created with Guid.NewGuid().ToString().ToUpper(), then a unique mutex name would look like this:

_ServiceControllerUtility_192A9AC4-1317-4340-816E-80A497EC1A83_

A detailed example how to create and use a named mutex can be found in the documentation article about Mutex Constructor.

The second parameter of the Mutex constructor - isFirstInstance - is the important one - if it is true, then the mutex does not yet exist and this means, that the unique code is not yet called.

mutex = new Mutex(true, uniqueApplicationDescription, out isFirstInstance);

Using Anonymous delegates to make the helper flexible

Because every application code is different, the helper class should be able to execute dynamic code. This is possible in C# using Action Delegates and Lambda expressions.

Examples of Action delegates and lambda expressions:

void Main()
{
    Action<int> print = i => Console.WriteLine(i);

    execute (() => Console.WriteLine("Hello, world!"));
    execute (() => print(2 + 2));
}

private void execute(Action action)
{
    action();
}

In this case the parameter onceInstanceAction of the Start method is of type Action, and it should be used to call the code, that starts the application.

public static void Start(string uniqueApplicationDescription, string applicationTitle, Action oneInstanceAction, Action instanceNotUniqueAction = null)...

Using the helper class

The helper class creates the mutex and runs the given code once, on the first application start. The default behaviour, if the application is started again, is to show a message box to inform the user.

SingleInstance.Start("uniqueMutexName", "Application title", () =>
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new ApplicationForm());
});

Sometimes this is not sufficient - for example every attempt after the first one, should be logged. For that case the class accepts a second anonymous delegate, that overrides the default behaviour if the first action is already executed:

Action customAlreadyStartedBehaviourAction = () =>
{
    Logger.WriteInformation(string.Format("{0} - Application is already running.", DateTime.Now.ToShortTimeString()));
};

SingleInstance.Start("uniqueMutexName", "Application title", () =>
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new ApplicationForm());
}, customAlreadyStartedBehaviourAction);

The complete helper class can be downloaded from this gist: SingleInstance.cs.

Comments and feedback are always appreciated.

 
Share this