2009-04-22 6 views
8

У меня есть приложение .NET, в котором я разрешаю запускать только один процесс во время, однако время от времени это приложение используется на ящиках Citrix и, как таковое, может выполняться несколькими пользователями на одном компьютере.Как проверить выполняемый процесс на сеанс пользователя?

Я хочу проверить и убедиться, что приложение работает только один раз за сеанс пользователя, потому что прямо сейчас, если пользователь A запускает приложение, тогда пользователь B получает сообщение «Приложение уже используется», а не должен.

Это то, что я теперь проверяет запущенный процесс:

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 
      } 

ответ

6

EDIT: Улучшение ответа в соответствии с this cw question ...

Вы можете использовать мьютекс для проверки кастрированного барана приложение уже работает:

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(); 
    } 
} 

Немаловажным является AppGuid - вы можете сделать это зависит от пользователя.

Может быть, вы хотите, чтобы прочитать эту статью: the misunderstood mutex

+0

Работы для меня. Благодаря! – Russ

3

Как tanascius уже есть, вы можете использовать мьютекс.

На сервере, на котором запущены службы терминалов, именованный системный мьютекс может иметь два уровня видимости. Если его имя начинается с префикса «Глобальный», мьютекс отображается во всех сеансах сервера терминалов. Если его имя начинается с префикса «Локальный», мьютекс отображается только на сеансе сервера терминалов, где он был создан.

Источник: msdn, Mutex Class

0

Если Form1 запускает без фоновых потоков, а Form1 выходит, у вас есть проблема: мьютекс освобождается, но этот процесс все еще там. Что-то вдоль линий ниже лучше ИМХО:

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 
      ); 
     } 
    } 
} 

Мьютексы не будет выпущен до тех пор, как основной домен приложения еще до. И это будет продолжаться до тех пор, пока приложение работает.

0

Просто заявка очевидна - хотя Mutex обычно считается лучшим решением, вы все же можете решить проблему с одним экземпляром за сеанс без Mutex - просто проверьте SessionId.

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)

Смежные вопросы