c# - que - Ejecuta una sola instancia de una aplicación usando Mutex
para que sirve mutex en c# (7)
Para permitir solo una instancia única de una aplicación en ejecución, estoy usando mutex. El código se da a continuación. ¿Esta es la manera correcta de hacerlo? ¿Hay algún defecto en el código?
Cómo mostrar la aplicación que ya se está ejecutando cuando el usuario intenta abrir la aplicación por segunda vez. Actualmente (en el código a continuación), solo estoy mostrando un mensaje de que ya se está ejecutando otra instancia.
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");
}
}
Eche un vistazo a esta pregunta
Hay un enlace a este artículo: http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx donde se explica el uso de un mutex.
Lo hice de esta manera una vez, espero que ayude:
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;
}
Mira la muestra del código que se muestra en esta página
En resumen, utiliza la sobrecarga Mutex ctor(bool, string, out bool)
que le dice a través de un parámetro Out, si obtuvo la propiedad de Named Mutex. Si es la primera instancia, este parámetro externo contendrá verdadero después de que se llame al ctor, en cuyo caso procederá como de costumbre. Si este parámetro es falso, significa que otra instancia ya tiene propiedad / se está ejecutando, en cuyo caso mostrará un mensaje de error "Ya se está ejecutando otra instancia". y luego salir con gracia
Utilice la aplicación con el tiempo de espera y la configuración de seguridad. Usé mi clase personalizada:
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();
}
}
}
y úsala:
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");
}
}
Yo uso esto:
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();
}
}
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());
}
}
Fuente: http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx