Garantindo apenas uma instância de aplicativo

Duplicar Possível:
Qual é a maneira correta de criar um aplicativo de instância única?

Eu tenho um aplicativo Winforms, que lança uma canvas inicial através do seguinte código:

Hide(); bool done = false; // Below is a closure which will work with outer variables. ThreadPool.QueueUserWorkItem(x => { using (var splashForm = new SplashScreen()) { splashForm.Show(); while (!done) Application.DoEvents(); splashForm.Close(); } }); Thread.Sleep(3000); done = true; 

O acima está no codebehind do formulário principal e é chamado a partir do manipulador de events load.

No entanto, como posso garantir que apenas uma instância do aplicativo seja carregada por vez? No manipulador de events load do formulário principal, eu poderia verificar se a lista de processos está no sistema (via GetProcessesByName (…)), mas existe um método melhor?

Usando o .NET 3.5.

GetProcessesByName é uma maneira lenta de verificar se outra instância está em execução. O método mais rápido e elegante está usando o mutex:

 [STAThread] static void Main() { bool result; var mutex = new System.Threading.Mutex(true, "UniqueAppId", out result); if (!result) { MessageBox.Show("Another instance is already running."); return; } Application.Run(new Form1()); GC.KeepAlive(mutex); // mutex shouldn't be released - important line } 

Por favor, tenha em mente que o código que você apresentou não é a melhor abordagem. Como foi recomendado em um dos comentários chamando DoEvents () em um loop não é a melhor idéia.

 static class Program { // Mutex can be made static so that GC doesn't recycle // same effect with GC.KeepAlive(mutex) at the end of main static Mutex mutex = new Mutex(false, "some-unique-id"); [STAThread] static void Main() { // if you like to wait a few seconds in case that the instance is just // shutting down if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false)) { MessageBox.Show("Application already started!", "", MessageBoxButtons.OK); return; } try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } finally { mutex.ReleaseMutex(); } // I find this more explicit } } 

Uma nota sobre o some-unique-id -> deve ser única na máquina, então use algo como o nome da sua empresa / nome do aplicativo.

Editar:

http://sanity-free.org/143/csharp_dotnet_single_instance_application.html