Click here to Skip to main content
Click here to Skip to main content

Mutex Process Identifier

, 23 Jul 2010
Rate this:
Please Sign up or sign in to vote.
A simple workaround for identifying the owner process of a mutex.

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();
    //get current running processes
    bool InstanceRunning = false;
    //this field will show us if an instance is already running
    long runningId = 50000;
    //here we hold the PID of the eventual running instance
    foreach (Process p in runningProcesses)
    {
        try
        {
            Mutex newinstanceMutex = 
              Mutex.OpenExisting("Global\\MUTEXPIDBYCHYROPTERON" + p.Id.ToString());
             //we check if a Mutex that respects our format is already created
            try
            {
                newinstanceMutex.ReleaseMutex();
            }
            catch { }
            InstanceRunning = true;
            //if the upper Mutex.OpenExisting succeeds, a mutex is already created, so
            //an instance signaling the searched mutex is already running
            runningId = p.Id;
            break;
        }
        catch { }
    }
    if (!InstanceRunning)
    {
        Mutex currentMutex = new Mutex(true, 
          "Global\\MUTEXPIDBYCHYROPTERON" + 
          Process.GetCurrentProcess().Id.ToString());
        //if no instance is running we create a new "signaling" Mutex
        //as you can see, the unique string that I chose
        //is "Global\\MUTEXPIDBYCHYROPTERON"
        currentMutex.ReleaseMutex();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        MutexPID_ mainFrm = new MutexPID_();
        Application.Run(mainFrm);
    }
    else
    {
        //this code execution occurs if a running application instance was found
        IntPtr winHandle = Process.GetProcessById((int)runningId).MainWindowHandle;
        //we now bring the process with PID = runningID to front
        if (winHandle != IntPtr.Zero)
        {
            const int SW_RESTORE = 9;
            if (IsIconic(winHandle) != 0) ShowWindow(winHandle, SW_RESTORE);
            SetForegroundWindow(winHandle);
        }
        Environment.Exit(0);
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Zozel

Romania Romania
Young programmer from Vaslui city, waiting to finish school
and slide through faculty. Big Grin | :-D
Programming was always one of my pleasures, started with
primitive programming languages like BP 7.0 and BC++ for DOS,
also tasted Borland C++ Builder, Visual C++, VB, but fell in love with C#.
 
In my spare time, besides programming, I enjoy nature, sports, movies, riding my bike, etcetera, etcetera..
I'm also addicted to music.

Comments and Discussions

 
GeneralThe common solution... Pinmemberpeterchen23-Jul-10 20:14 
GeneralRe: The common solution... PinmemberZozel25-Jul-10 1:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140814.1 | Last Updated 24 Jul 2010
Article Copyright 2010 by Zozel
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid