2009-07-30 11 views
12

Ok, quindi ho creato la mia applicazione C#, ho creato un programma di installazione e l'ho installato sul mio computer.Limita più istanze di un'applicazione

Il problema è che quando l'utente apre l'exe dell'applicazione due volte, saranno in esecuzione due istanze dell'applicazione. Voglio sempre che una istanza dell'applicazione sia in esecuzione in qualsiasi momento, come faccio a fare questo?

Grazie per il vostro aiuto,

risposta

9

La tecnica comuni per questo è di creare un nome Mutex e verificare la sua presenza sul all'avvio dell'applicazione.

Vedere this o this.

Codice da 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

Si prega di mostrare il codice nella risposta. Il primo collegamento era morto e altri potrebbero alla fine seguire l'esempio. – nothingisnecessary

0

non so l'ambiente che si sta operando, ma qualcosa da tenere a mente su 'applicazioni singola istanza' è come si definisce a istanza singola. Se l'applicazione può essere eseguita su più workstation allo stesso tempo, utilizzando un'origine dati comune, si tratta di un problema? Allo stesso modo, per quanto riguarda una situazione di servizi terminal (o una situazione di "esecuzione come") in cui più di un utente è registrato nello stesso computer, si desidera limitare l'applicazione in modo tale che solo un'istanza per utente, per -computer? O stai bene semplicemente essendo una istanza per utente?

La risposta a questi potrebbe portarti in una direzione piuttosto che un'altra. Ad esempio, abbiamo un'applicazione 'single-instance' con scope che è un gruppo di computer. È consentito un solo utente all'interno di quel gruppo di workstation. Siamo riusciti a farlo disponendo di una tabella nella nostra fonte di dati condivisa che monitorava gli utenti attualmente connessi. Questo è un problema di manutenzione in quanto è necessario essere sicuri che la tabella sia sempre accurata al 100%. Gestire le cose come interruzioni di alimentazione impreviste sulla workstation, lasciando i record "fasulli" in quella tabella ha richiesto un trattamento accurato.

4

Con grazie Messrs.Allen e 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

Il display del codice sembra essere espulso da @ "Global \" - le mie scuse. – lance

8

i risolto questo problema questo

[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 
    } 

è semplice, ma ho avuto appena il tempo di verificare le soluzioni migliori.

+0

Se qualcuno prende una copia dell'applicazione con un nome diverso e inizia come un nuovo processo, ci saranno più istanze. Quindi utilizza i campi 'processObject.MainModule.FileInfo' come la descrizione o il nome del file originale .. che non cambiano anche se il file eseguibile viene rinominato – Sanjay