2009-04-22 11 views
8

Ich habe eine .NET-Anwendung, die ich nur erlauben, einen einzelnen Prozess zu einem Zeitpunkt auszuführen, jedoch wird diese Anwendung von Zeit zu Zeit auf Citrix-Boxen verwendet und kann daher von mehreren Benutzern auf demselben Computer ausgeführt werden.Wie kann ich nach einem laufenden Prozess pro Benutzersitzung suchen?

Ich möchte überprüfen und stellen Sie sicher, dass die Anwendung nur einmal pro Benutzersitzung ausgeführt wird, denn jetzt, wenn Benutzer A die App ausführt, erhält Benutzer B die Meldung "App bereits verwendet" und sollte nicht.

Das ist, was ich habe jetzt, dass die Kontrollen für den laufenden Prozess:

Process[] p = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName); 
      if (p.Length > 1) 
      { 
#if !DEBUG 
       allowedToOpen &= false; 
       errorMessage += 
        string.Format("{0} is already running.{1}", Constants.AssemblyTitle, Environment.NewLine); 
#endif 
      } 

Antwort

6

EDIT: Verbesserte die Antwort nach this cw question ...

Sie einen Mutex zur Überprüfung, ob die verwenden können App bereits läuft:

using(var mutex = new Mutex(false, AppGuid)) 
{ 
    try 
    { 
     try 
     { 
      if(!mutex.WaitOne(0, false)) 
      { 
       MessageBox.Show("Another instance is already running."); 
       return; 
      } 
     } 
     catch(AbandonedMutexException) 
     { 
      // Log the fact the mutex was abandoned in another process, 
      // it will still get aquired 
     } 

     Application.Run(new Form1()); 
    } 
    finally 
    { 
     mutex.ReleaseMutex(); 
    } 
} 

Wichtig ist die AppGuid - man könnte es auf den Benutzer abhängig machen.

Vielleicht gefällt Ihnen diesen Artikel lesen: the misunderstood mutex

+0

für mich Works. Vielen Dank! – Russ

3

Wie tanascius schon sagen, können Sie die Mutex verwenden.

Auf einem Server, auf dem Terminaldienste ausgeführt werden, kann ein benannter Systemmutex über zwei Sichtbarkeitsebenen verfügen. Wenn der Name mit dem Präfix "Global \" beginnt, ist der Mutex in allen Terminalserver-Sitzungen sichtbar. Wenn der Name mit dem Präfix "Local \" beginnt, ist der Mutex nur in der Terminalserversitzung sichtbar, in der er erstellt wurde.

Quelle: msdn, Mutex Class

0

Wenn Form1 startet Nicht-Hintergrund-Threads, und das Form1 verlässt, haben Sie ein Problem: der Mutex freigegeben wird, aber der Prozess ist immer noch da. Etwas nach der folgenden Zeile ist besser IMHO:

static class Program { 
    private static Mutex mutex; 



    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() { 
     bool createdNew = true; 
     mutex = new Mutex(true, @"Global\Test", out createdNew); 
     if (createdNew) { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1());   
     } 
     else { 
      MessageBox.Show(
       "Application is already running", 
       "Error", 
       MessageBoxButtons.OK, 
       MessageBoxIcon.Error 
      ); 
     } 
    } 
} 

Der Mutex wird nicht so lange freigegeben werden, da die primäre Anwendungsdomäne ist nach wie vor hoch. Und das wird so lange dauern, wie die Anwendung läuft.

0

Nur unter Angabe der offensichtlichen - obwohl Mutex wird in der Regel als bessere Lösung betrachtet, können Sie immer noch die Single-Instance-pro-Problem lösen ohne Mutex - nur die SessionId testen.

private static bool ApplicationIsAlreadyRunning() 
    { 
     var currentProcess = Process.GetCurrentProcess(); 
     var processes = Process.GetProcessesByName(currentProcess.ProcessName); 

     // test if there's another process running in current session. 
     var intTotalRunningInCurrentSession = processes.Count(prc => prc.SessionId == currentProcess.SessionId); 

     return intTotalRunningInCurrentSession > 1; 
    } 

Source (no Linq)

Verwandte Themen