2009-05-04 6 views
19

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 failles dans le code?Exécution d'une seule instance d'une application à l'aide de Mutex

Comment afficher l'application en cours d'exécution lorsque l'utilisateur essaie d'ouvrir l'application une deuxième fois. À l'heure actuelle (dans le code ci-dessous), je suis juste l'affichage d'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"); 

     }    
    } 
+0

en double de http://stackoverflow.com/questions/646480/is-using-a-mutex-to-prevent-multipule -instances-of-the-same-program-from-running –

+0

Assurez-vous de lire ceci: http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global -mutex-in-c/229567 –

Répondre

8

Je l'ai fait de cette façon une fois, je l'espère 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; 
} 
+18

Ce code n'est pas sûr ou correct: http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in -c/229567 –

+2

J'aurais aimé que c'était sûr et correct. C'est très simple et peut être facilement écrit sans presque aucune pensée lol. +1 à vous deux, cependant. –

+0

Ce code fonctionne dans le code de débogage mais pas dans la version exe !!! –

1

Découvrez l'exemple de code figurant sur this page

En bref, vous utilisez la Mutex de surcharge ctor(bool, string, out bool) qui vous indique via un paramètre out, si vous avez la propriété du mutex nommé. Si vous êtes la première instance, ce paramètre out contiendra true après l'appel de ctor - auquel cas vous continuez comme d'habitude. Si ce paramètre est faux, cela signifie qu'une autre instance a déjà 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 avec élégance.

7
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

+1

Ce code n'est pas sûr ou correct ... http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567 –

+1

' Global 'le rend global à la machine, pas à l'utilisateur courant. Ainsi, dans un environnement de serveur ou sur des services de terminal, un seul utilisateur peut l'exécuter à la fois. Je pense que la plupart des utilisateurs s'attendent à ce qu'une seule instance signifie une seule instance pour eux. –

1

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

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"); 
     } 
    } 
Questions connexes