2011-06-17 15 views
28

posibles duplicados:
What is the correct way to create a single instance application?
Return to an already open application when a user tries to open a new instancecómo comprobar si otra instancia de la aplicación se está ejecutando

Podría alguien mostrar cómo es posible comprobar si otra instancia del programa (por ejemplo, test.exe) se está ejecutando y, si es así, detenga la aplicación para que no se cargue si existe una instancia existente.

+2

Ver http://stackoverflow.com/questions/94274/return-to-an-already-open-application-when-a-user-tries-to-open-a-new-instance y HTTP : //stackoverflow.com/questions/184084/how-to-force-c-net-app-to-run-only-one-instance-in-windows – ChrisF

+0

http://www.codeproject.com/KB/cs /restricting_instances.aspx –

+0

@Tim Schmelter Gracias, pero esto es para una aplicación de GUI, la mía es una aplicación de consola – Tom

Respuesta

93

Quieres algo de código en serio? Aquí está.

var exists = System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Count() > 1; 

Esto funciona para cualquier aplicación (cualquier nombre) y se convertirá en true si hay otra instancia en ejecución de la misma aplicación.

Editar: para solucionar sus necesidades, puede utilizar cualquiera de estos:

if (System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Count() > 1) return; 

de su método principal para salir del método ... O

if (System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Count() > 1) System.Diagnostics.Process.GetCurrentProcess().Kill(); 

que matará el proceso actualmente cargar instantáneamente.


es necesario agregar una referencia a System.Core.dll para el método de extensión .Count(). Alternativamente, puede usar la propiedad .Length.

+0

Devolver en su segundo fragmento solo hace que ambas aplicaciones mueran, por lo que ahora hay 0 en ejecución en vez de 2. –

+0

@ dsp_099 A menos que ambos comiencen casi exactamente al mismo tiempo o alguien ejecute este código en un ciclo infinito de alguna manera, ganaron ' t. Puedes ver claramente '.Count> 1' allí. – Vercas

+0

Sí, no funcionó bien para mí ya que las dos aplicaciones se ejecutan a través de msconfig/autostart, siempre se inició double –

0

La clase estática de proceso tiene un método GetProcessesByName() que puede usar para buscar a través de procesos en ejecución. Simplemente busque cualquier otro proceso con el mismo nombre ejecutable.

0

Puede probar este

Process[] processes = Process.GetProcessesByName("processname"); 
foreach (Process p in processes) 
{ 
    IntPtr pFoundWindow = p.MainWindowHandle; 
    // Do something with the handle... 
    // 
} 
+0

@R Quijano ¿Es esta una forma segura de hacerlo? – Tom

+0

@R Quijano Esto no funciona si estás ejecutando el mismo ejecutable !! – Tom

10

Aquí hay algunas buenas aplicaciones de muestra. A continuación hay una forma posible.

public static Process RunningInstance() 
{ 
    Process current = Process.GetCurrentProcess(); 
    Process[] processes = Process.GetProcessesByName (current.ProcessName); 

    //Loop through the running processes in with the same name 
    foreach (Process process in processes) 
    { 
     //Ignore the current process 
     if (process.Id != current.Id) 
     { 
      //Make sure that the process is running from the exe file. 
      if (Assembly.GetExecutingAssembly().Location. 
       Replace("/", "\\") == current.MainModule.FileName) 

      { 
       //Return the other process instance. 
       return process; 

      } 
     } 
    } 
    //No other instance was found, return null. 
    return null; 
} 


if (MainForm.RunningInstance() != null) 
{ 
    MessageBox.Show("Duplicate Instance"); 
    //TODO: 
    //Your application logic for duplicate 
    //instances would go here. 
} 

Muchas otras formas posibles. Vea los ejemplos de alternativas.

First one.

Second One.

Third One

EDIT 1: acabo de ver su comentario de que usted tiene una aplicación de consola. Eso se discute en el second sample.

+0

Gracias la entrada :) – Tom

+0

Dos enlaces rotos. – RenniePet

45

No es seguro lo que quiere decir con 'el programa', pero si desea limitar su aplicación a una instancia, entonces puede usar un Mutex para asegurarse de que su aplicación aún no se está ejecutando.

[STAThread] 
static void Main() 
{ 
    Mutex mutex = new System.Threading.Mutex(false, "MyUniqueMutexName"); 
    try 
    { 
     if (mutex.WaitOne(0, false)) 
     { 
      // Run the application 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new MainForm()); 
     } 
     else 
     { 
      MessageBox.Show("An instance of the application is already running."); 
     } 
    } 
    finally 
    { 
     if (mutex != null) 
     { 
      mutex.Close(); 
      mutex = null; 
     } 
    } 
} 
+3

¿Por qué un voto a favor? Esto responde la pregunta sin dudas. Por favor explique por qué esta no es una respuesta satisfactoria. – Patrik

+0

¿Qué sucede si su programa es "asesinado"? ¿Decir si el programa se bloqueó o se usó el explorador de procesos para matar la aplicación de una manera "antipática"? ¿La única forma de resolverlo sería reiniciar la PC? – TamusJRoyce

+0

Consideraré que este método probablemente funcione en múltiples usuarios. Puede ser un mejor método para cosas como servicios de Windows, mono en otras plataformas, y tal. – TamusJRoyce

Cuestiones relacionadas