Although there are many resources online, I just want to add a bookmark at my own place.
A customer used Microsoft.VisualBasic.ApplicationServices to facilitate a single-instance C# application.
He wants the same applications to run as single instance respectively in different directories.
Microsoft.VisualBasic.ApplicationServices way is to use the GUID from AssmeblyInfo to uniquely identify the application at the build time.
So the key point here is to find out a "runtime GUID".
At start, I was thinking of twist .NET remoting to achieve this.
But after reading several articles, the idea of using System.Threading.Mutex to consume a "runtime GUID" proves to be a simple and elegant solution.
A Basic support for single-instance applications is fairly straightforward, and there are a variety of approaches to handling this. All of them involve some sort of shared resource that instances of the application can create and lock. If a second instance of an application is not successful in doing so, it knows that a previous instance already exists and that it should exit.
The most common shared resource used in managed applications for the creation of single-instance applications is a mutex. A mutex is a synchronization primitive provided by the operating system that allows for interthread and interprocess communication. A mutex is typically used to protect a shared resource, providing exclusive access to it.
When one thread acquires the mutex, no other threads will be able to acquire it until the thread that did so originally releases it. As such, applications can use a mutex to provide single-instance functionality. On startup, the application will attempt to create and acquire a mutex with a known name. If it can, then it is the first instance. If it can't, then another instance of the application has already created and acquired the mutex, thus alerting this new instance to the fact that it is a duplicate and should exit.
In the .NET Framework, a mutex is represented through the System.Threading.Mutex class. This class derives from WaitHandle and is a thin wrapper around the kernel's mutex object, which can be created using the Win32
® CreateMutex function and opened using the Win32 OpenMutex function.
First, you need to come up with a name for the mutex. The use of a name allows multiple instances of the application to create or access the same mutex instance, so choosing a unique name ahead of time is important. Some typical examples of names used for this purpose include the name of the entry assembly for the application (available from [Assembly].GetEntryAssembly().FullName), the entry assembly's type library GUID (accessed with Marshal.GetTypeLibGuidForAssembly), or a predefined GUID used to uniquely identify the application. The name can also be autogenerated at runtime, but the algorithm for doing so must be created in such a way that all instances of the same application will generate the same name. With the name in hand, a mutex is instantiated using the constructor that accepts three arguments.
The following code ensures a single-instance of the C#.NET Winform application:
Hash path
Assembly execAsm = Assembly.GetExecutingAssembly();
SHA1Managed sha = new SHA1Managed();
string asmLocHash = Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(execAsm.Location)));
// mutexName = GUID + Ver Major.Minor + Asm Location Hash
string mutexName = Marshal.GetTypeLibGuidForAssembly(execAsm).ToString() +
string.Format("{0}.{1}", execAsm.GetName().Version.Major, execAsm.GetName().Version.Minor) +
asmLocHash;
By the way, the code above needs to add more references:
using System.Threading;
using System.Security.Cryptography;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
Reference:
http://msdn.microsoft.com/en-us/magazine/cc163741.aspx
http://www.codeproject.com/KB/cs/CSSIApp.aspx
http://blogs.msdn.com/onoj/archive/2004/06/04/148532.aspx