Using C# and WPF under .NET (rather than Windows Forms or console), what is the correct way to create an application that can only be run as a single instance?
I know it has something to do with some mythical thing called a mutex, rarely can I find someone that bothers to stop and explain what one of these are.
The code needs to also inform the already-running instance that the user tried to start a second one, and maybe also pass any command-line arguments if any existed.
Here is what I use. It combined process enumeration to perform switching and mutex to safeguard from "active clickers":
Not using Mutex though, simple answer:
Put it inside the
Program.Main()
.Example:
You can add
MessageBox.Show
to theif
-statement and put "Application already running".This might be helpful to someone.
Update 2017-01-25. After trying few things, I decided to go with VisualBasic.dll it is easier and works better (at least for me). I let my previous answer just as reference...
Just as reference, this is how I did without passing arguments (which I can't find any reason to do so... I mean a single app with arguments that as to be passed out from one instance to another one). If file association is required, then an app should (per users standard expectation) be instanciated for each doc. If you have to pass args to existing app, I think I would used vb dll.
Not passing args (just single instance app), I prefer not registering a new Window message and not override the message loop as defined in Matt Davis Solution. Although it's not a big deal to add a VisualBasic dll, but I prefer not add a new reference just to do single instance app. Also, I do prefer instanciate a new class with Main instead of calling Shutdown from App.Startup override to ensure to exit as soon as possible.
In hope that anybody will like it... or will inspire a little bit :-)
Project startup class should be set as 'SingleInstanceApp'.
WindowHelper:
You should never use a named mutex to implement a single-instance application (or at least not for production code). Malicious code can easily DoS (Denial of Service) your ass...
I added a sendMessage Method to the NativeMethods Class.
Apparently the postmessage method dosent work, if the application is not show in the taskbar, however using the sendmessage method solves this.
Here is a very good article regarding the Mutex solution. The approach described by the article is advantageous for two reasons.
First, it does not require a dependency on the Microsoft.VisualBasic assembly. If my project already had a dependency on that assembly, I would probably advocate using the approach shown in the accepted answer. But as it is, I do not use the Microsoft.VisualBasic assembly, and I'd rather not add an unnecessary dependency to my project.
Second, the article shows how to bring the existing instance of the application to the foreground when the user tries to start another instance. That's a very nice touch that the other Mutex solutions described here do not address.
UPDATE
As of 8/1/2014, the article I linked to above is still active, but the blog hasn't been updated in a while. That makes me worry that eventually it might disappear, and with it, the advocated solution. I'm reproducing the content of the article here for posterity. The words belong solely to the blog owner at Sanity Free Coding.