在终端服务器情况下,我想确保每个用户只运行一个应用程序实例。
这样做的最佳方式是什么?
这是我目前使用的,但似乎它没有按预期工作。我不能百分之百。
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,因为并非所有客户端都会按照每个用户名跟踪一个物理人员,并且用户可以多次登录服务器。
答案 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
并不十分熟悉