Introduction
A few days ago, I was making a simple application and I needed to find a way to prevent multiple instances of it to run. Googled a bit, and found the Mutex-way. In addition, if an instance of my application was already running, I needed to "find" it in order to bring its main window to the front. The problem was that I didn't know which process represented the already-opened application instance. Finding the process that owns the opened Mutex would have solved the problem. Again, Googled a bit more, but found no solution, so I had to figure it out myself. I came up with a simple workaround, and thought it would be nice to post the solution here for whoever needs it.
Background
The attached zip, as its name suggests, contains the source of an application that illustrates the idea. The project needs to be opened with Visual Studio 2010.
Using the code
The idea is to include the PID of the running application instance in the Mutex's unique name. The Mutex's name has the format <our_unique_string>+<current_Application_PID>.
The unique string can be any string that you can think of, as long as you make sure that its uniqueness is strong enough to avoid cases in which other running applications create Mutex-es with a similar name as your application's.
So, first of all, when we open the application, we search for a Mutex that respects our format.
In order to do so, we need to get the IDs of the currently opened processes, and check if a Mutex with the name <our_unique_string>+<current_PID> was created.
Here's the code (Program.cs):
[DllImport("user32.dll")]
private static extern int ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
private static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int IsIconic(IntPtr hWnd);
[STAThread]
static void Main()
{
Process[] runningProcesses = Process.GetProcesses();
bool InstanceRunning = false;
long runningId = 50000;
foreach (Process p in runningProcesses)
{
try
{
Mutex newinstanceMutex =
Mutex.OpenExisting("Global\\MUTEXPIDBYCHYROPTERON" + p.Id.ToString());
try
{
newinstanceMutex.ReleaseMutex();
}
catch { }
InstanceRunning = true;
runningId = p.Id;
break;
}
catch { }
}
if (!InstanceRunning)
{
Mutex currentMutex = new Mutex(true,
"Global\\MUTEXPIDBYCHYROPTERON" +
Process.GetCurrentProcess().Id.ToString());
currentMutex.ReleaseMutex();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MutexPID_ mainFrm = new MutexPID_();
Application.Run(mainFrm);
}
else
{
IntPtr winHandle = Process.GetProcessById((int)runningId).MainWindowHandle;
if (winHandle != IntPtr.Zero)
{
const int SW_RESTORE = 9;
if (IsIconic(winHandle) != 0) ShowWindow(winHandle, SW_RESTORE);
SetForegroundWindow(winHandle);
}
Environment.Exit(0);
}
}