web-dev-qa-db-fra.com

Exécuter une seule instance d'une application à l'aide de Mutex

Afin de n'autoriser qu'une seule instance d'une application en cours d'exécution, j'utilise mutex. Le code est donné ci-dessous. Est-ce que c'est la bonne façon de le faire? Y a-t-il des défauts dans le code?

Comment afficher l'application déjà en cours d'exécution lorsque l'utilisateur essaie d'ouvrir l'application la deuxième fois. À l'heure actuelle (dans le code ci-dessous), j'affiche simplement un message qu'une autre instance est déjà en cours d'exécution.

    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");

        }            
    }
25
blitzkriegz

Je l'ai fait de cette façon une fois, j'espère que ça aide:

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;
}
16
Peter D
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

7
Milen

J'utilise ceci:

    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();
        }
    }    
3
algreat

Utilisez l'application avec des paramètres de délai d'attente et de sécurité. J'ai utilisé ma classe personnalisée:

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();
            }
        }
    }

et l'utiliser:

    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");
        }
    }
1
vivlav

Jetez un oeil à cette question

Il y a un lien vers cet article: le mutex incompris où l'utilisation d'un mutex est expliquée.

1
tanascius

Découvrez l'exemple de code affiché sur cette page

En bref, vous utilisez la surcharge Mutex ctor(bool, string, out bool) qui vous indique, via un paramètre out, si vous avez obtenu la propriété du mutex nommé. Si vous êtes la première instance, ce paramètre de sortie contiendrait true après l'appel du ctor - auquel cas vous procédez comme d'habitude. Si ce paramètre est faux, cela signifie qu'une autre instance a déjà obtenu la propriété/est en cours d'exécution, auquel cas vous affichez un message d'erreur "Une autre instance est déjà en cours d'exécution." puis quittez gracieusement.

1
Gishu
0
aJ.