2009-07-30 19 views
12

De acuerdo, entonces creé mi aplicación C#, creé un instalador para ella y la tengo instalada en mi máquina.Restringir varias instancias de una aplicación

El problema es que cuando el usuario abre el exe de la aplicación dos veces, habrá dos instancias de la aplicación ejecutándose. Solo quiero que una instancia de la aplicación se ejecute en cualquier momento, ¿cómo hago esto?

Gracias por su ayuda,

Respuesta

9

La técnica común para esto es crear un llamado Mutex y comprobar si su presencia al iniciar la aplicación.

Ver this o this.

Código de DDJ:

class App : Form 
{ 
    Mutex mutex; 

    App() 
    { 
     Text = "Single Instance!"; 
     mutex = new Mutex(false, "SINGLE_INSTANCE_MUTEX"); 
     if (!mutex.WaitOne(0, false)) 
     { 
      mutex.Close(); 
      mutex = null; 
     } 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (disposing) 
      mutex.ReleaseMutex(); 
     base.Dispose(disposing); 
    } 

    static void Main() 
    { 
     App app = new App(); 
     if (app.mutex != null) Application.Run(app); 
     else MessageBox.Show("Instance already running"); 
    } 
} 
+0

Por favor, muestre el código en la respuesta. El primer enlace estaba muerto, y otros pueden seguir su ejemplo. – nothingisnecessary

0

no sé el ambiente que se está operando en, pero es algo a tener en cuenta acerca de instancia única 'aplicaciones' es cómo se defina de instancia única. Si la aplicación se puede ejecutar en varias estaciones de trabajo al mismo tiempo, utilizando un origen de datos común, ¿es eso un problema? Del mismo modo, ¿qué ocurre con una situación de servicios de terminal (o una situación de "ejecutar como") donde más de un usuario está conectado a la misma computadora? ¿Desea restringir la aplicación de forma tal que solo una instancia por usuario, por -¿computadora? ¿O estás de acuerdo con que sea simplemente una instancia por usuario?

La respuesta a esto podría llevarlo en una dirección sobre otra. Por ejemplo, tenemos una aplicación de "instancia única" cuyo alcance es un grupo de computadoras. Solo se permite un usuario dentro de ese grupo de estaciones de trabajo. Logramos esto al tener una tabla en nuestra fuente de datos compartida que rastreó a los usuarios actualmente conectados. Este es un problema de mantenimiento, ya que necesita asegurarse de que la tabla sea 100% precisa todo el tiempo. Manejar cosas como cortes de energía inesperados en la estación de trabajo, dejando registros "falsos" en esa tabla tomaron un manejo cuidadoso.

4

Con gracias a Messrs.Allen y Powell:

static void Main() 
    { 
     using (Mutex mutex = new Mutex(false, @"Global\" + appGuid)) { 
      if (!mutex.WaitOne(0, false)) { 
       string processName = GetProcessName(); 
       BringOldInstanceToFront(processName); 
      } 
      else { 
       GC.Collect(); 
       Application.Run(new Voting()); 
      } 
     } 
    } 

    private static void BringOldInstanceToFront(string processName) { 
     Process[] RunningProcesses = Process.GetProcessesByName(processName); 
     if (RunningProcesses.Length > 0) { 
      Process runningProcess = RunningProcesses[0]; 
      if (runningProcess != null) { 
       IntPtr mainWindowHandle = runningProcess.MainWindowHandle; 
       NativeMethods.ShowWindowAsync(mainWindowHandle, (int) WindowConstants.ShowWindowConstants.SW_SHOWMINIMIZED); 
      NativeMethods.ShowWindowAsync(mainWindowHandle, (int) WindowConstants.ShowWindowConstants.SW_RESTORE); 
      } 
     } 
    } 
+0

La visualización del código parece haber sido descartada por el @ "Global \" - mis disculpas. – lance

8

i resuelto este problema por esta

[STAThread] 
static void Main() 
    { 

     Process[] result = Process.GetProcessesByName("ApplicationName"); 
     if (result.Length > 1) 
     { 
      MessageBox.Show("There is already a instance running.", "Information"); 
      System.Environment.Exit(0); 
     } 
     // here normal start 
    } 

es simple, pero apenas había tiempo para comprobar si hay mejores soluciones.

+0

Si alguien toma una copia de la aplicación con un nombre diferente y comienza como un nuevo proceso, habrá múltiples instancias. Así que haga uso de los campos 'processObject.MainModule.FileInfo' como la descripción o el nombre del archivo original ... que no cambian incluso si se renombra el archivo ejecutable – Sanjay

Cuestiones relacionadas