检查应用程序是否已在当前用户下运行

时间:2013-10-16 18:35:12

标签: c# .net wpf terminal-services

在终端服务器情况下,我想确保每个用户只运行一个应用程序实例。

这样做的最佳方式是什么?

这是我目前使用的,但似乎它没有按预期工作。我不能百分之百。

int SID = Process.GetCurrentProcess().SessionId;

Process current_process = Process.GetCurrentProcess();
int proc_count = 0;

foreach (Process p in Process.GetProcessesByName(current_process.ProcessName))
{
    proc_count++;
    if (p.SessionId.Equals(SID))
    {
        if (proc_count > 1)
        {
            Application.Current.Shutdown();
            return;
        }
    }
}

更新 的 为了帮助澄清我已阅读的评论,我认为它需要脱离会话ID,因为并非所有客户端都会按照每个用户名跟踪一个物理人员,并且用户可以多次登录服务器。

2 个答案:

答案 0 :(得分:2)

普遍接受的方法是使用命名的互斥锁。通过创建命名互斥锁,您可以确定另一个实例是否已在运行并关闭新实例。

此代码应该为您提供所需的结果。假设所有这些都在可执行文件的主要入口点。

bool createdMutex;
using (var processMutex = new System.Threading.Mutex(false, "Some name that is unique for the executable", out createdMutex)) {

   if (!createdMutex)
     ; // some other instance of the application is already running (or starting up). You may want to bring the other instance to foreground (assuming this is a GUI app)
   else 
   {
      // this is the process to actually run..
      // do application init stuff here
   }
}

请注意,我在这里输入了代码,因此可能存在语法错误,拼写错误和其他意外误导。

作为评论中的请求,以下是选择互斥锁名称的一些方向:

如果要将应用程序限制为每个终端服务器会话的单个实例,请选择应用程序唯一的互斥锁名称。

如果要在终端服务器会话中将应用程序限制为每个“user”的单个实例,请选择应用程序特有的互斥锁名称,并附加用户的SID。 WindowsIdentity.GetCurrent()将为您提供SecurityIdentifier

如果要将应用程序限制为每个用户的单个实例,无论哪个终端服务器会话,请选择一个互斥名称,该名称对于包含用户SID的应用程序是唯一的,并在名称前加上“Global”。< / p>

如果要将应用程序限制为每个服务器的单个实例,请选择应用程序唯一的互斥锁名称,并使用“Global \”前缀。

值得注意的是,虽然终端服务器会话与单个用户关联,但这并不意味着会话中运行的所有应用程序都与该用户相关联(请考虑“运行方式”选项)。

答案 1 :(得分:0)

在数据库status = 1或0

中放置一行

1表示他正在

0意味着他已经离开了

if(status==0)
{
    //let him in
}
else
{
    //dont let him into the system
}

希望这对结构/逻辑有所帮助,因为我对c#或.net

并不十分熟悉