0

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

做这个的最好方式是什么?

这是我目前正在使用的,但它似乎没有按预期工作。我不能 100% 相信这一点。

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,因为并非所有客户端都会按照每个用户名跟随一个物理人,并且用户可以多次登录服务器。

4

2 回答 2

1

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

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

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

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

作为评论中的要求,这里是选择互斥锁名称的一些方向:

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

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

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

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

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

于 2013-10-16T18:45:28.803 回答
0

在数据库中放入一行 status = 1 或 0

1意味着他在

0意味着他离开了

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

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

于 2013-10-16T18:40:23.140 回答