C# 使用EventWaitHandle确保跨多个用户的单个实例
合作者已经建立了一个原型,使用处理连接到Sparkfun RFID阅读器,我认为使用USB串行连接。我们已经将原型部署到了许多试用者的家中,我愚蠢地忽略了一个常见的使用场景是用户切换。因此,我正在编写一个包装器,以确保只有一个原型应用程序实例在机器上的所有用户之间运行 我正在测试我的第一个尝试,作为一个简单的控制台应用程序。代码如下:C# 使用EventWaitHandle确保跨多个用户的单个实例,c#,user-accounts,single-instance,event-wait-handle,C#,User Accounts,Single Instance,Event Wait Handle,合作者已经建立了一个原型,使用处理连接到Sparkfun RFID阅读器,我认为使用USB串行连接。我们已经将原型部署到了许多试用者的家中,我愚蠢地忽略了一个常见的使用场景是用户切换。因此,我正在编写一个包装器,以确保只有一个原型应用程序实例在机器上的所有用户之间运行 我正在测试我的第一个尝试,作为一个简单的控制台应用程序。代码如下: static void Main(string[] args) { // http://stackoverflow.com/a/2
static void Main(string[] args)
{
// http://stackoverflow.com/a/2590446/575530
var users = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var rule = new EventWaitHandleAccessRule(users, EventWaitHandleRights.FullControl, AccessControlType.Allow);
var security = new EventWaitHandleSecurity();
security.AddAccessRule(rule);
bool createdStartup;
using (var whStartup = new EventWaitHandle(false, EventResetMode.AutoReset, "Global/AaltoTokensAppStartupEvent", out createdStartup, security))
{
bool createdShutdown;
using (var whShutdown = new EventWaitHandle(false, EventResetMode.AutoReset, "Global/AaltoTokensAppShutdownEvent", out createdShutdown, security))
{
Console.WriteLine("Let other instances shutdown");
whStartup.Set();
Console.WriteLine("If other instances exist wait for them to shutdown");
if (!createdShutdown)
{
whShutdown.WaitOne();
}
whShutdown.Reset();
Console.WriteLine("Start tray app");
var tokenProc = Process.Start(@"C:\Temp\FAMILY3_WIN\TokensApp.exe");
Console.WriteLine(tokenProc.ProcessName);
Console.WriteLine("Wait to see if another instance to tries to start");
whStartup.Reset();
whStartup.WaitOne();
Console.WriteLine("Shutdown if another instance starts");
//if (tokenProc != null) tokenProc.Kill();
foreach (var process in Process.GetProcesses())
{
if (process.ProcessName.StartsWith("javaw"))
{
process.Kill();
}
}
whShutdown.Set();
}
}
Console.WriteLine("Done...");
Console.ReadLine();
}
(注意:我知道这段代码存在以下问题:(1)杀死不是运行原型的Java进程;(2)没有代码来响应同时启动的大量实例,一次只启动两个实例。但这不是我的问题所在。)
在单个用户帐户下测试这一点很好。我可以启动我的应用程序,它反过来启动原型,如果我启动我的应用程序的第二个实例,第一个实例将杀死原型的初始实例,第二个实例将重新启动原型的另一个实例
但如果我尝试从两个不同的用户帐户执行此操作,则会失败(无声)。如果我
有人能看到我的代码有什么问题吗?我应该如何在同一台机器上的多个同时的用户会话中使用EventWaitHandle?不是一直都是这样吗?在写了一个长问题几分钟后,答案就会跃入我的脑海 我以EventWaitHandle的名义把斜杠划错了方向。例如,替换构造函数调用:
new EventWaitHandle(false, EventResetMode.AutoReset, "Global/AaltoTokensAppShutdownEvent", out createdShutdown, security)
关于这一点:
new EventWaitHandle(false, EventResetMode.AutoReset, @"Global\AaltoTokensAppShutdownEvent", out createdShutdown, security)
修复了我的问题。事件对象不是这里的合适对象,它受到无法解决的竞争条件的影响。使用互斥是一个样板,它有一个构造函数返回createdNew bool,告诉你你的进程首先到达那里。谢谢,这很有趣。我认为在这种情况下,我相对不受竞赛条件的影响,因为启动第二个应用程序的机制需要时间。我开始使用两个互斥体,但换成了事件,我将进一步探讨。