2009-07-30 10 views
12

Okay, also ich habe meine C# -Anwendung erstellt, ein Installationsprogramm für es erstellt und es funktioniert auf meinem Computer installiert.Beschränken Sie mehrere Instanzen einer Anwendung

Das Problem ist, wenn der Benutzer die Anwendung exe zweimal öffnet, gibt es zwei Instanzen der Anwendung ausgeführt wird. Ich möchte immer nur eine Instanz der Anwendung laufen lassen, wie gehe ich vor?

Danke für Ihre Hilfe,

Antwort

9

Die übliche Technik hierfür ist ein benannte Mutex und prüfen, ob seine Anwesenheit beim Start der Anwendung zu erstellen.

Siehe this oder this.

-Code von 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

Bitte Code in Antwort zeigen. Die erste Verbindung war tot, und andere mögen vielleicht folgen. – nothingisnecessary

0

Ich weiß nicht, die Umgebung, die Sie in Betrieb sind, aber etwas im Auge zu behalten über 'Single-Instance-Anwendungen' ist, wie Sie Einzelinstanz definieren. Wenn die Anwendung auf mehreren Arbeitsstationen gleichzeitig mit einer gemeinsamen Datenquelle ausgeführt werden kann, ist das ein Problem? Ähnlich verhält es sich mit einer Terminal-Services-Situation (oder einer "Run-as-Situation"), bei der mehr als ein Benutzer am selben Computer angemeldet ist. Möchten Sie die Anwendung so einschränken, dass nur eine Instanz pro Benutzer, per -Computer? Oder sind Sie damit einverstanden, dass es nur eine Instanz pro Benutzer ist?

Die Antwort auf diese kann Sie in eine Richtung über eine andere führen. Zum Beispiel haben wir eine Single-Instance-Anwendung, wobei der Bereich eine Gruppe von Computern ist. In dieser Gruppe von Arbeitsstationen ist nur ein Benutzer zugelassen. Wir haben dies geschafft, indem wir eine Tabelle in unserer freigegebenen Datenquelle haben, die aktuell verbundene Benutzer verfolgt. Dies ist ein Wartungsproblem, da Sie sicherstellen müssen, dass die Tabelle zu jeder Zeit 100% genau ist. Die Handhabung von Dingen wie unerwarteten Stromausfällen auf der Workstation und das Zurücklassen "gefälschter" Datensätze in dieser Tabelle erforderte einige sorgfältige Handhabung.

4

Mit Dank an Messrs.Allen und 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

Die Codeanzeige scheint vom @ "Global" abgeworfen zu werden - meine Entschuldigung. – lance

8

i löste dieses Problem durch diese

[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 einfach ist, aber ich hatte kaum Zeit für bessere Lösungen zu überprüfen.

+0

Wenn jemand eine Kopie der Anwendung unter einem anderen Namen erstellt und als neuer Prozess startet, gibt es mehrere Instanzen. Verwenden Sie also '' processObject.MainModule.FileInfo''-Felder wie Beschreibung oder Originaldateiname, die sich nicht ändern, selbst wenn die ausführbare Datei umbenannt wird – Sanjay