2010-08-23 21 views
6

Escribí un programa en C# ahora me gustaría saber cuál es la manera correcta de evitar que el programa se inicie si ya se está ejecutando.evitar que una aplicación C# ejecute más de una instancia

por lo que si ya se está ejecutando, y hace doble clic en el programa, no se iniciará porque ya se está ejecutando.

Puedo hacerlo, pero estaba pensando en una forma estándar y adecuada.

+1

duplicados de http://stackoverflow.com/questions/3211529/net-4-single-application-instance –

Respuesta

10

La forma recomendada de hacer esto es con un mutex sistema.

bool createdNew; 
using(var mutex = new System.Threading.Mutex(true, "MyAppName", out createdNew)) 
{ 
    if (createdNew) 
     // first instance 
     Application.Run(); 
    else 
     MessageBox.Show("There is already an instace running"); 
} 

El primer parámetro para el cúter Mutex le dice que cree crear un mutex amplio para este hilo. Si el Mutex ya existe, devolverá false a través del tercer parámetro.

actualización
Dónde poner esto? Pondré esto en program.cs. Si lo coloca en form_load, deberá mantener el mutex durante el tiempo de vida de la aplicación (tener el mutex como miembro en el formulario) y liberarlo manualmente en el formulario de descarga.
Cuanto antes llame a esto, mejor, antes de que la otra aplicación abra conexiones DB, etc. y antes de que se creen recursos para formularios/controles etc.

+2

No creo que esta es la forma recomendada * * si esto ya encapsulado en [WindowsFormsApplicationBase] (http://msdn.microsoft.com/en-us/library/microsoft.visualbasic .applicationservices.windowsformsapplicationbase.issingleinstance.aspx) – Oliver

+0

este aspecto fresco, pero http://msdn.microsoft.com/en-us/library/system.threading.mutex%28v=VS.80%29.aspx (Precaución: Una Mutex abandonado indica un error grave en el código. Cuando un hilo sale sin liberar el mutex, las estructuras de datos protegidas por el mutex pueden no estar en un estado consistente. El siguiente hilo para solicitar la propiedad del mutex puede manejar esta excepción y continuar, si se puede verificar la integridad de las estructuras de datos), ¿qué pasa con esto? Yo uso .NET v2 –

+0

@Oliver: Eso está en el espacio de nombres de VB, esta es una pregunta de C#. –

4

Manera rápida que hice en una de las aplicaciones .. Puede consultar la lista de procesos en ejecución para ver si la aplicación actual ya se está ejecutando y no volver a iniciar la aplicación.

Process[] lprcTestApp = Process.GetProcessesByName("TestApplication"); 
if (lprcTestApp.Length > 0) 
{ 
     // The TestApplication is already running, don't run it again 
} 
+0

Y es la forma correcta ... – RameshVel

+0

Esto no funcionaría si alguien creara una aplicación con el mismo nombre de archivo que otra aplicación. –

+0

estaba pensando exactamente en éste –

2

Creo que la enumeración de la lista de procesos podría ser lenta. También puede crear un Mutex usando la clase System.Threading.Mutex y verificar si ya se creó cuando se inicia el proceso. Sin embargo, esto requeriría llamar al código del sistema Win32 para que no sea completamente independiente de la plataforma.

0

Si su aplicación produce/consume archivos, entonces es mejor que registre un un mecanismo de comunicación de todo el sistema (p. ej., un punto de acceso remoto o WCF, o incluso un socket). Luego, si la segunda instancia de la aplicación se inicia desde hacer doble clic en uno de sus archivos, puede enviar la información del archivo a la instancia en ejecución.

De lo contrario, si se trata de un programa independiente, como otros han dicho, un Mutex o semáforo serviría igual de bien.

2

Eche un vistazo a Scotts blog post y no se deje engañar por el nombre del ensamblado. Es solo un nombre de archivo de un archivo estándar en .Net Framework.

Aquí hay más información directa de MSDN para el WindowsFormsApplicationBase.

0

solución en la aplicación de formulario de Windows Prohibir nuevamente la ejecución de la aplicación (volver a abrir la aplicación).

1- primer Agregar clase RunAlready.cs

2-Call método processIsRunning() con el nombre de proceso de RunAlready.cs en el Programa.cs

Program.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Tirage.MainStand 
{ 
static class Program 
{ 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     PublicClass.Class.RunAlready RunAPP = new PublicClass.Class.RunAlready(); 
     string outApp = RunAPP.processIsRunning("Tirage.MainStand"); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     MainStand_FrmLogin fLogin = new MainStand_FrmLogin(); 
     if (outApp.Length == 0) 
     { 

      if (fLogin.ShowDialog() == DialogResult.OK) 
      { 
       Application.Run(new MainStand_masterFrm()); 

      } 
     } 
     else MessageBox.Show("Instance already running"); 

     } 
    } 
} 

clase RunAlready:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace PublicClass.Class 
{ 
    public class RunAlready 
    { 
     public string processIsRunning(string process) 
     { 
     string xdescription = ""; 
     System.Diagnostics.Process[] processes = 
      System.Diagnostics.Process.GetProcessesByName(process); 
     foreach (System.Diagnostics.Process proc in processes) 
     { 
      var iddd = System.Diagnostics.Process.GetCurrentProcess().Id; 
      if (proc.Id != System.Diagnostics.Process.GetCurrentProcess().Id) 
      { 
       xdescription = "Application Run At time:" + proc.StartTime.ToString() + System.Environment.NewLine; 
       xdescription += "Current physical memory : " + proc.WorkingSet64.ToString() + System.Environment.NewLine; 
       xdescription += "Total processor time : " + proc.TotalProcessorTime.ToString() + System.Environment.NewLine; 
       xdescription += "Virtual memory size : " +   proc.VirtualMemorySize64.ToString() + System.Environment.NewLine; 
      } 
     } 


     return xdescription; 
    } 
} 
} 
Cuestiones relacionadas