Click here to Skip to main content
15,880,725 members
Articles / Programming Languages / C#

Mutex Process Identifier

Rate me:
Please Sign up or sign in to vote.
4.90/5 (9 votes)
23 Jul 2010CPOL1 min read 48.5K   532   19   10
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):

C#
[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)


Written By
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

 
GeneralA Few Issues Come to Mind... Pin
Blake Miller22-Sep-10 10:59
Blake Miller22-Sep-10 10:59 
GeneralPassing parameter to runing program Pin
Kim Togo27-Jul-10 0:59
professionalKim Togo27-Jul-10 0:59 
GeneralRe: Passing parameter to runing program Pin
Corneliu Zuzu28-Jul-10 0:07
Corneliu Zuzu28-Jul-10 0:07 
hey Kim, thanks for the info.
one question - if you pass the parameter to the already running program, can you get an answer back?
also...one more disadvantage here is that the program's name can vary - for instance, if I have C:\foo1.exe and
D:\foo2.exe, I can't pass parameters both ways - that's why finding the PROCESS's ID of the already running instance
is most reliable - if you know the PID of the already running instance, you can also get the process's name afterwards,
so you can also safely use the method you posted Smile | :) Big Grin | :-D
GeneralRe: Passing parameter to runing program Pin
Kim Togo28-Jul-10 0:52
professionalKim Togo28-Jul-10 0:52 
GeneralMy vote of 5 Pin
JS0000126-Jul-10 3:47
JS0000126-Jul-10 3:47 
GeneralRe: My vote of 5 Pin
Corneliu Zuzu28-Jul-10 0:10
Corneliu Zuzu28-Jul-10 0:10 
GeneralMy vote of 5 Pin
beuzozel26-Jul-10 1:31
beuzozel26-Jul-10 1:31 
GeneralRe: My vote of 5 Pin
Corneliu Zuzu28-Jul-10 0:10
Corneliu Zuzu28-Jul-10 0:10 
GeneralThe common solution... Pin
peterchen23-Jul-10 20:14
peterchen23-Jul-10 20:14 
GeneralRe: The common solution... Pin
Corneliu Zuzu25-Jul-10 1:42
Corneliu Zuzu25-Jul-10 1:42 

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

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