What, Why and How with Mutex object.
Mutex is nothing but mutual exclusion. It is quick way to ensure that only one instance of your program is running is to have it create a mutex with a specific name because another copy of it is already running and owns the same mutex.
Mutex object provides exclusive access to shared resources and synchronize threads in different processes. Also it ensures blocks of code are executed only once at a time.
Most common requirement from client is creating single instance application that will block the user from launching more than one instance of a program at a time.
There are many ways to do this one of them is using searching the process table.
Process table can be used to ensure that you have only one instance running by searching process table for processes that were launched from the same .exe file.
We will cover below points with C# Mutex.
- Restore application if minimized.
- Restore application from system tray.
To achieve first and second requirement we will use WinAPI functions to activate the window and bring it to the foreground. We will use WinAPI’s PostMessage function it requires less code compare to others. We should consider few points while using HNDL_BROADCAST. What if the message code which we are using is duplicate or some other applications use internally for their own purposes, then the application could behave strange. To avoid this is to use RegisterWindowMessage().
Below piece of code creates App Mutex for creating single instance app .
[DllImport("user32")] public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); [STAThread] static void Main () { public static readonly int SINGLEINSTANCE_APP = WinApi.RegisterWindowMessage("SINGLEINSTANCE_APP|{0}", ProgramInfo.AssemblyGuid); static Mutex mutex; public const int HNDL_BROADCAST = 0xffff; bool onlyInstance = false; string mutexName = String.Format("Global\\{0}",AssemblyGuid); mutex = new Mutex(true, mutexName, out onlyInstance); if (!onlyInstance) { PostMessage((IntPtr) HNDL_BROADCAST, SINGLEINSTANCE_APP,IntPtr.Zero, IntPtr.Zero); return; } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); try { MainForm mainForm = new MainForm(); Application.Run(mainForm); } catch (Exception e) { MessageBox.Show(e.Message); } mutex.ReleaseMutex();
Add below method in main form.
protected override void WndProc(ref Message message) { if (message.Msg == SINGLEINSTANCE_APP) { ShowWindow(); } base.WndProc(ref message); } Note that Mutex name should be unique across applications it is better to use assembly GUID to avoid any strange behaviours.