by Nicolás Ferreira
2. February 2009 00:00
Para esto, pueden utilizar la siguiente clase:
using System;
using System.Threading;
namespace NicolasFerreira.Utilities
{
//* **************************************************
//* Author: Nicolás Ferreira (http://nicolasferreira.com/)
//* **************************************************
/// <summary>
/// This class uses EventWaitHandle. It lets you know if another instance of your application is already running. Also, if there is already a running instance of your application and someone try to start another, the main one will be notified.
/// </summary>
public static class SingleInstanceApplication
{
private static EventWaitHandle _EventWaitHandle;
private static object _lock = new object();
private static bool _Opened;
private static Thread _WaitOneHandlerThread;
private static bool _RaiseAnotherTriedToRunEvent;
public delegate void AnotherTriedToRunEventHandler();
public static event AnotherTriedToRunEventHandler AnotherTriedToRun;
/// <summary>
/// Gets a value that indicates whether single instance application monitor is open.
/// </summary>
public static bool Opened
{
get
{
return _Opened;
}
}
/// <summary>
/// Opens the single instance application monitor.
/// </summary>
/// <param name="uniqueInstanceName">A name that identifies your application as unique.</param>
/// <returns>true if the system-wide EventWaitHandle could be created (the calling instance is single). false if the calling instance should terminate.</returns>
public static bool Open(string uniqueInstanceName)
{
return Open(uniqueInstanceName, false);
}
/// <param name="local">true if each terminal server session can run an instance of your application. Otherwise, false.</param>
public static bool Open(string uniqueInstanceName, bool local)
{
if (string.IsNullOrEmpty(uniqueInstanceName))
throw new ArgumentException("uniqueInstanceName cannot be blank.");
else if (_Opened)
throw new InvalidOperationException("Single instance application monitor is open.");
lock (_lock)
{
bool createdNew;
_EventWaitHandle = new EventWaitHandle(
false,
EventResetMode.AutoReset,
string.Concat(local ? "Local\\" : "Global\\", uniqueInstanceName),
out createdNew);
if (createdNew)
{
_Opened = true;
_RaiseAnotherTriedToRunEvent = true;
_WaitOneHandlerThread = new Thread(new ThreadStart(EventWaitHandleHandler));
_WaitOneHandlerThread.Start();
}
else
{
_Opened = false;
_RaiseAnotherTriedToRunEvent = false;
_EventWaitHandle.Set();
_EventWaitHandle.Close();
_EventWaitHandle = null;
}
}
return _Opened;
}
private static void EventWaitHandleHandler()
{
if (_EventWaitHandle != null)
{
while (_Opened)
{
_EventWaitHandle.WaitOne();
if ((_RaiseAnotherTriedToRunEvent) && (AnotherTriedToRun != null))
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
{
AnotherTriedToRun();
}));
}
}
}
/// <summary>
/// Closes the single instance application monitor and frees resources.
/// </summary>
public static void Close()
{
lock (_lock)
{
if (!_Opened)
throw new InvalidOperationException("Single instance application monitor is not open.");
_Opened = false;
_RaiseAnotherTriedToRunEvent = false;
_EventWaitHandle.Set();
_EventWaitHandle.Close();
_EventWaitHandle = null;
}
}
}
}
Ejemplo en una aplicación consola:
static void Main(string[] args)
{
SingleInstanceApplication.AnotherTriedToRun += new SingleInstanceApplication.AnotherTriedToRunEventHandler(SingleInstanceApplication_AnotherTriedToRun);
if (!SingleInstanceApplication.Open("{63BAA9C4-849C-4b4a-8B9C-FC1D640F09E2}"))
{
Console.WriteLine("Another instance of this application is currently running.");
}
else
{
Console.WriteLine("This is the main instance of your application.");
Console.ReadLine();
if (SingleInstanceApplication.Opened)
{
SingleInstanceApplication.Close();
}
}
}
static void SingleInstanceApplication_AnotherTriedToRun()
{
Console.WriteLine(string.Format("{0}: Another instance of this application tried to run.",
DateTime.Now.ToString()));
}
Ejemplo en una aplicación Windows Forms:
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (SingleInstanceApplication.Open("{4C8C7928-55FD-45e8-A13E-895C5EE4D0C3}"))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
if (SingleInstanceApplication.Opened)
{
SingleInstanceApplication.Close();
}
}
else
{
MessageBox.Show("Another instance of this application is currently running.");
}
}
private void Form1_Load(object sender, EventArgs e)
{
SingleInstanceApplication.AnotherTriedToRun += new SingleInstanceApplication.AnotherTriedToRunEventHandler(SingleInstanceApplication_AnotherTriedToRun);
}
void SingleInstanceApplication_AnotherTriedToRun()
{
MessageBox.Show(string.Format("{0}: Another instance of this application tried to run.",
DateTime.Now.ToString()));
}
Descargar el código.