如何检查每个用户会话的运行进程?

我有一个.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 } 

编辑:根据这个cw问题改进答案…

您可以使用互斥锁检查应用程序是否已运行:

 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 – 您可以依赖于用户。

也许你喜欢读这篇文章: 被误解的互斥体

正如tanascius所说,你可以使用Mutex。

在运行终端服务的服务器上,命名系统互斥锁可以具有两个级别的可见性。 如果其名称以前缀“Global \”开头,则互斥锁在所有终端服务器会话中都可见。 如果其名称以前缀“Local \”开头,则互斥锁仅在创建它的终端服务器会话中可见。

资料来源: msdn,Mutex Class

如果Form1启动非后台线程,并且Form1退出,则表示您遇到了问题:已释放互斥锁但该进程仍然存在。 下面的东西是更好的恕我直言:

 static class Program { private static Mutex mutex; ///  /// The main entry point for the application. ///  [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 ); } } } 

只要主应用程序域仍处于运行状态,就不会释放互斥锁。 只要应用程序正在运行,这将会存在。

只是说明显而易见的 – 虽然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; } 

来源(没有Linq)