Question

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 at-il des défauts dans le code?

Comment afficher l'application en cours d'exécution lorsque l'utilisateur tente d'ouvrir l'application pour la deuxième fois. À l'heure actuelle (dans le code ci-dessous), j'affiche simplement un message indiquant 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");

        }            
    }
Était-ce utile?

La solution

Je l’ai fait de cette façon une fois, j’espère que cela aidera:

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

Autres conseils

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

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

Consultez cette question

Il existe un lien vers cet article: le mutex mal compris où l'utilisation d'un mutex est expliquée.

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

En bref, vous utilisez le mutex de surcharge ctor (bool, string, out bool) qui vous indique, via un paramètre out, si vous êtes devenu propriétaire du mutex nommé. Si vous êtes la première instance, ce paramètre out contiendra true après l'appel du ctor - auquel cas vous procéderez comme d'habitude. Si ce paramètre est défini sur false, cela signifie qu'une autre instance possède déjà la propriété / est en cours d'exécution. Dans ce cas, vous affichez un message d'erreur "Une autre instance est déjà en cours d'exécution". puis quittez gracieusement.

Utilisez l'application avec les 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");
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top