26

In order to allow only a single instance of an application running I'm using mutex. The code is given below. Is this the right way to do it? Are there any flaws in the code?

How to show the already running application when user tries to open the application the second time. At present (in the code below), I'm just displaying a message that another instance is already running.

    static void Main(string[] args)
    {
        Mutex _mut = null;

        try
        {
            _mut = Mutex.OpenExisting(AppDomain.CurrentDomain.FriendlyName);
        }
        catch
        {
             //handler to be written
        }

        if (_mut == null)
        {
            _mut = new Mutex(false, AppDomain.CurrentDomain.FriendlyName);
        }
        else
        {
            _mut.Close();
            MessageBox.Show("Instance already running");

        }            
    }
blitzkriegz
  • 8,618
  • 15
  • 52
  • 71
  • Duplicate of http://stackoverflow.com/questions/646480/is-using-a-mutex-to-prevent-multipule-instances-of-the-same-program-from-running – David Schmitt May 04 '09 at 12:10
  • Make sure you read this: http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567 – Sam Saffron May 04 '09 at 12:54

7 Answers7

17

I did it this way once, I hope it helps:

bool createdNew;

Mutex m = new Mutex(true, "myApp", out createdNew);

if (!createdNew)
{
    // myApp is already running...
    MessageBox.Show("myApp is already running!", "Multiple Instances");
    return;
}
Peter D
  • 4,702
  • 2
  • 27
  • 30
  • 23
    This code is not safe or correct: http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567 – Sam Saffron May 04 '09 at 12:56
  • 3
    I wish this was safe and correct. It's very simple and can be easily written without hardly any thought at all lol. +1 to the both of you, though. – jay_t55 Jun 18 '13 at 09:31
  • @SamSaffron - Are you saying it is unsafe and incorrect only in scenarios where the mutex may be requested by multiple users OR is it unsafe and incorrect in scenarios where the mutex will only be requested by a single user as well? – dugas Dec 19 '14 at 19:50
  • 5
    I disagree with Sam's comment (and the downvotes). The code does not use mutex synchronization. Instead the mutex is only used to determine if already created by another process and will be destroyed when the process terminates including abnormal termination. I'll deem it safe and correct until seeing an explanation why it would be incorrect. Problems might be a rogue application grabbing the mutex and the process running twice within different sessions. The former is sabotage, the latter covered by the question ("*user* tries to open the application the second time"). – Paul B. May 31 '18 at 17:22
  • In which function of my C# application this should be placed? – Tak Jul 14 '20 at 07:30
8
static void Main() 
{
  using(Mutex mutex = new Mutex(false, @"Global\" + appGuid))
  {
    if(!mutex.WaitOne(0, false))
    {
       MessageBox.Show("Instance already running");
       return;
    }

    GC.Collect();                
    Application.Run(new Form1());
  }
}

Source : http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

Milen
  • 5,473
  • 5
  • 19
  • 12
  • 1
    This code is not safe or correct... http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567 – Sam Saffron May 04 '09 at 12:56
  • 1
    'Global' makes it global to the machine, not the running user. Thus in a server environment or over terminal services, only one user could run it at a time. I would think most users expect a single instance to mean a single instance for them. – Paul Alexander Aug 31 '11 at 03:11
3

I use this:

    private static Mutex _mutex;

    private static bool IsSingleInstance()
    {
        _mutex = new Mutex(false, _mutexName);

        // keep the mutex reference alive until the normal 
        //termination of the program
        GC.KeepAlive(_mutex);

        try
        {
            return _mutex.WaitOne(0, false);
        }
        catch (AbandonedMutexException)
        {
            // if one thread acquires a Mutex object 
            //that another thread has abandoned 
            //by exiting without releasing it

            _mutex.ReleaseMutex();
            return _mutex.WaitOne(0, false);
        }
    }


    public Form1()
    {
        if (!isSingleInstance())
        {
            MessageBox.Show("Instance already running");
            this.Close();
            return;
        }

        //program body here
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (_mutex != null)
        {
            _mutex.ReleaseMutex();
        }
    }    
algreat
  • 7,762
  • 5
  • 38
  • 52
1

Use app with timeout and security settings. I used my custom class:

private class SingleAppMutexControl : IDisposable
    {
        private readonly Mutex _mutex;
        private readonly bool _hasHandle;

        public SingleAppMutexControl(string appGuid, int waitmillisecondsTimeout = 5000)
        {
            bool createdNew;
            var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                MutexRights.FullControl, AccessControlType.Allow);
            var securitySettings = new MutexSecurity();
            securitySettings.AddAccessRule(allowEveryoneRule);
            _mutex = new Mutex(false, "Global\\" + appGuid, out createdNew, securitySettings);
            _hasHandle = false;
            try
            {
                _hasHandle = _mutex.WaitOne(waitmillisecondsTimeout, false);
                if (_hasHandle == false)
                    throw new System.TimeoutException();
            }
            catch (AbandonedMutexException)
            {
                _hasHandle = true;
            }
        }

        public void Dispose()
        {
            if (_mutex != null)
            {
                if (_hasHandle)
                    _mutex.ReleaseMutex();
                _mutex.Dispose();
            }
        }
    }

and use it:

    private static void Main(string[] args)
    {
        try
        {
            const string appguid = "{xxxxxxxx-xxxxxxxx}";
            using (new SingleAppMutexControl(appguid))
            {

                Console.ReadLine();
            }
        }
        catch (System.TimeoutException)
        {
            Log.Warn("Application already runned");
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Fatal Error on running");
        }
    }
vivlav
  • 11
  • 2
1

Have a look at this question

There is a link to this article: the misunderstood mutex where the usage of a mutex is explained.

Community
  • 1
  • 1
tanascius
  • 50,043
  • 21
  • 106
  • 130
1

Check out the code sample shown on this page

In short, you use the overload Mutex ctor(bool, string, out bool) which tells you via an out parameter, whether you got ownership of the Named Mutex. If you're the first instance, this out param would contain true after the ctor is called - in which case you proceed as usual. If this param is false, it means another instance has already got ownership/is running, in which case you show an error message "Another instance is already running." and then exit gracefully.

Community
  • 1
  • 1
Gishu
  • 126,803
  • 45
  • 214
  • 298
0

Also this. Is using a Mutex to prevent multiple instances of the same program from running safe?

Community
  • 1
  • 1
aJ.
  • 32,074
  • 21
  • 79
  • 124