¿Prevenir múltiples instancias de una aplicación determinada en .NET?

En .NET, ¿cuál es la mejor manera de evitar que se ejecuten varias instancias de una aplicación al mismo tiempo? Y si no hay una “mejor” técnica, ¿cuáles son algunas de las advertencias a considerar con cada solución?

Use Mutex. Uno de los ejemplos anteriores que usan GetProcessByName tiene muchas salvedades. Aquí hay un buen artículo sobre el tema:

http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

[STAThread] static void Main() { using(Mutex mutex = new Mutex(false, "Global\\" + appGuid)) { if(!mutex.WaitOne(0, false)) { MessageBox.Show("Instance already running"); return; } Application.Run(new Form1()); } } private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9"; 
 if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1) { AppLog.Write("Application XXXX already running. Only one instance of this application is allowed", AppLog.LogMessageType.Warn); return; } 

Aquí está el código que necesita para asegurarse de que solo se está ejecutando una instancia. Este es el método de usar un mutex con nombre.

 public class Program { static System.Threading.Mutex singleton = new Mutex(true, "My App Name"); static void Main(string[] args) { if (!singleton.WaitOne(TimeSpan.Zero, true)) { //there is already another instance running! Application.Exit(); } } } 

Hanselman tiene una publicación sobre el uso de la clase WinFormsApplicationBase del ensamblado Microsoft.VisualBasic para hacer esto.

Parece que hay 3 técnicas fundamentales que se han sugerido hasta ahora.

  1. Derive de la clase Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase y establezca la propiedad IsSingleInstance en true. (Creo que una advertencia aquí es que esto no funcionará con las aplicaciones de WPF, ¿o sí?)
  2. Use un mutex con nombre y verifique si ya se ha creado.
  3. Obtenga una lista de procesos en ejecución y compare los nombres de los procesos. (Esto tiene la advertencia de requerir que el nombre de su proceso sea único en relación con cualquier otro proceso que se ejecute en la máquina de un usuario determinado).

¿Alguna advertencia que me he perdido?

Probé todas las soluciones aquí y nada funcionó en mi proyecto C # .net 4.0. Con la esperanza de ayudar a alguien aquí, la solución que funcionó para mí:

Como variables de clase principal:

 private static string appGuid = "WRITE AN UNIQUE GUID HERE"; private static Mutex mutex; 

Cuando necesite verificar si la aplicación ya se está ejecutando:

 bool mutexCreated; mutex = new Mutex(true, "Global\\" + appGuid, out mutexCreated); if (mutexCreated) mutex.ReleaseMutex(); if (!mutexCreated) { //App is already running, close this! Environment.Exit(0); //i used this because its a console app } 

Necesitaba cerrar otras istancias solo con algunas condiciones, esto funcionó bien para mi propósito

Usando Visual Studio 2005 o 2008 cuando crea un proyecto para un ejecutable, en las ventanas de propiedades dentro del panel “Aplicación” hay una checkbox llamada “Hacer aplicación de instancia única” que puede activar para convertir la aplicación en una aplicación de instancia única .

Aquí hay una captura de la ventana de la que estoy hablando: enter image description here Este es un proyecto de aplicación de Windows Visual Studio 2008.

Este artículo simplemente explica cómo puede crear una aplicación de Windows con control sobre el número de sus instancias o ejecutar solo una instancia. Esta es una necesidad muy típica de una aplicación comercial. Ya hay muchas otras soluciones posibles para controlar esto.

http://www.openwinforms.com/single_instance_application.html

Use VB.NET! No realmente 😉

utilizando Microsoft.VisualBasic.ApplicationServices;

WindowsFormsApplicationBase de VB.Net le proporciona una propiedad “SingleInstace”, que determina otras instancias y permite que solo se ejecute una instancia.

Tienes que usar System.Diagnostics.Process.

Consulte: http://www.devx.com/tips/Tip/20044

Este es el código para VB.Net

 Private Shared Sub Main() Using mutex As New Mutex(False, appGuid) If Not mutex.WaitOne(0, False) Then MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error) Return End If Application.Run(New Form1()) End Using End Sub 

Este es el código para C #

 private static void Main() { using (Mutex mutex = new Mutex(false, appGuid)) { if (!mutex.WaitOne(0, false)) { MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Application.Run(new Form1()); } } 

(Nota: ¡esta es una solución divertida! Funciona pero usa un diseño malo GDI + para lograr esto.)

Coloque una imagen con su aplicación y cárguela al inicio. Sosténgalo hasta que la aplicación salga. El usuario no podrá iniciar una segunda instancia. (Por supuesto, la solución mutex es mucho más limpia)

 private static Bitmap randomName = new Bitmap("my_image.jpg"); 

Después de probar múltiples soluciones, la pregunta. Terminé usando el ejemplo para WPF aquí: http://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/

 public partial class App : Application { private static Mutex _mutex = null; protected override void OnStartup(StartupEventArgs e) { const string appName = "MyAppName"; bool createdNew; _mutex = new Mutex(true, appName, out createdNew); if (!createdNew) { //app is already running! Exiting the application Application.Current.Shutdown(); } } } 

En App.xaml:

 x:Class="*YourNameSpace*.App" StartupUri="MainWindow.xaml" Startup="App_Startup" 

1 – Crea una referencia en program.cs ->

 using System.Diagnostics; 

2 – Poner en el void Main() como la primera línea de código ->

  if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length >1) return; 

Eso es.

Simplemente usando un StreamWriter , ¿qué tal esto?

 System.IO.File.StreamWriter OpenFlag = null; //globally 

y

 try { OpenFlag = new StreamWriter(Path.GetTempPath() + "OpenedIfRunning"); } catch (System.IO.IOException) //file in use { Environment.Exit(0); } 

Normalmente se hace con un Mutex con nombre (use el nuevo Mutex (“el nombre de su aplicación”, verdadero) y verifique el valor de retorno), pero también hay algunas clases de soporte en Microsoft.VisualBasic.dll que pueden hacerlo por usted .

Esto funcionó para mí en C # puro. el try / catch es cuando posiblemente un proceso en la lista sale durante su ciclo.

 using System.Diagnostics; .... [STAThread] static void Main() { ... int procCount = 0; foreach (Process pp in Process.GetProcesses()) { try { if (String.Compare(pp.MainModule.FileName, Application.ExecutablePath, true) == 0) { procCount++; if(procCount > 1) { Application.Exit(); return; } } } catch { } } Application.Run(new Form1()); } 
 [STAThread] static void Main() // args are OK here, of course { bool ok; m = new System.Threading.Mutex(true, "YourNameHere", out ok); if (! ok) { MessageBox.Show("Another instance is already running."); return; } Application.Run(new Form1()); // or whatever was there GC.KeepAlive(m); // important! } 

De: Garantizar una instancia única de aplicación .NET

y: aplicación de instancia única Mutex

La misma respuesta que @Smink y @Imjustpondering con un giro:

Preguntas frecuentes de Jon Skeet sobre C # para descubrir por qué importa GC.KeepAlive

Asegúrese de considerar la seguridad al restringir una aplicación a una sola instancia:

Artículo completo: https://blogs.msdn.microsoft.com/oldnewthing/20060620-13/?p=30813

Estamos utilizando un mutex con nombre fijo para detectar si se está ejecutando otra copia del progtwig. Pero eso también significa que un atacante puede crear el mutex primero, lo que impide que nuestro progtwig se ejecute en absoluto. ¿Cómo puedo prevenir este tipo de ataque de denegación de servicio?

Si el atacante se ejecuta en el mismo contexto de seguridad en el que se está ejecutando su progtwig (o lo estaría), entonces no hay nada que pueda hacer. Cualquiera que sea el “saludo secreto” que se te ocurra para determinar si se está ejecutando otra copia de tu progtwig, el atacante puede imitarlo. Dado que se ejecuta en el contexto de seguridad correcto, puede hacer cualquier cosa que el progtwig “real” pueda hacer.

Evidentemente, no puede protegerse de un atacante que se ejecuta con el mismo privilegio de seguridad, pero igualmente puede protegerse contra atacantes no privilegiados que se ejecutan con otros privilegios de seguridad.

Intente configurar una DACL en su mutex, esta es la forma de .NET: https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.mutexsecurity(v=vs.110).aspx