A common requirement for application developers is an application that allows only a single instance. I can still remember the first time it came up for me. That was way back in the year 1999 – and I was a Delphi developer at the time. After diving into the middle of one of the “Mastering Delphi” books for two days, with no previous programming experience, having studied heavy current electrical engineering, I’d somehow managed to convince management to give me a chance as a developer. (I still don’t know how I got that right.) Those were fun times. I knew nothing about development, except that it fascinated me. I think it was nearly a week before I “discovered” that I could create my own classes. But maybe I’ll write about that another time.
The reason I’ve brought up my junior developer days is that, if you got here via a search on how to allow only one application instance, you probably haven’t been developing for long, and you might not ask yourself this important question: Is it really necessary? Preventing multiple instances is a step into the realm of taking control away from the user. Never fool yourself into thinking you are in control. Good software doesn’t dictate to it’s users how to behave. People use it because it does what they want, and many users, myself included, are quite ruthless about removing software they find annoying.
Of course there are often legitimate reasons for limiting the application to a single instance, and all the code presented here can be found in the zip file below.
My requirements for a single instance application
- Only one instance is allowed to run. (Of course.)
- The first instance must instantiate a form, the type of which is specified somehow.
- Any subsequent instances launched should do as follows:
- Do its best to select the existing instance and bring it to the front of the Z-order, even if it is minimized.
- Pass on any command-line arguments, if it was launched with arguments.
- In the event of the existing instance not responding, the new instance should not freeze; it should time out gracefully.
- Exit, regardless of whether the existing instance responded.
The universally accepted pattern to do this is to use a named system mutex, which then coordinates the access between the different processes. The logical way to implement this, in my mind, is to use an abstract class, with a generic type constraint and a Name property. This way, it’s easy to do all the work in the base class, making the derived type very simple to write. (Almost no code at all, and the type that will be instantiated as well as the name of the system mutex is baked into the design).
Here is my abstract base class:
Don’t worry about ApplicationExceptionLogger. That’s a flaky logging class of my own, and not necessary here. The optional to implement (virtual) ProcessCommandLineArguments method is also unnecessary fluff that I added to be able to send some arguments to be processed before instantiating the application.
The flow is straightforward. The first process will always own the mutex. It then creates the Form, with code almost identical to the code normally generated in an application’s program.cs file, except that it needs to use reflection to instantiate the form.
A subsequent process will not own the mutex, so it finds the first instance, and tries to activate it. Then, if it has any command line arguments to pass along, it does so by sending a WM_COPYDATA message. There is a good example of sending as well as receiving such messages on the Microsoft All-In-One Code Framework, in fact that is where my code to handle these messages comes from. There is however, a risk when sending the message. It has to be sent via the Windows API SendMessage function, and this function does not return until the receiver processes it. Of course, the implication of this is, if the first instance is frozen, and receives but never processes the message, the second instance will also freeze as it waits forever on the blocking call. Oops.
To work around this, I made a small change to the code that sends the WM_COPYDATA message. I made the method async, then offloaded the call to an asynchronous Task, via Task.Run. I then time out the call, if it takes longer than ten seconds. The extension method I use to time out the call, as well as loads of other goodies, can be found on the Parallel Programming with .Net blog.
Above, is the slightly altered call to SendMessage. Thanks to Microsoft’s parallel programming team’s awesome work, a potential disaster became trivial to solve.
Below are the Windows API functions that this code needed to access via platform invoke.
With all the work done by the base class, here is my application’s derived class. Note that it is mostly taken up by the unnecessary ProcessCommandLineArguments method. All that was really necessary here was to define the Name property. The type of form to instantiate (Splash) is also of course specified, since it is a type constraint in the abstract base class, and thus is specified in the signature of the derived class.
Normally, the type of form would indicate the main of the application, but in this case, I pass it the type of my splash screen, which is then responsible for instantiating my real main form.
Since all the work normally done in the generated program.cs file has been done manually, this also results in the Main method in program.cs now being only one line: new Romy.UI.Instance().Run();