使用 EventWaitHandle 确保跨多个用户的单个实例



合作者使用连接到Sparkfun RFID阅读器的Processing构建了一个原型,我认为使用USB上的串行连接。我们已经将原型部署到许多试用者的家中,我愚蠢地忽略了一个常见的使用场景是用户切换。因此,我正在编写一个包装器,以确保只有一个原型应用程序实例在计算机上的所有用户上运行。

正在测试我作为一个简单的控制台应用程序的第一个尝试。代码如下:

    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:TempFAMILY3_WINTokensApp.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)没有代码来响应同时启动的大量实例,一次只有两个。但这不是我的问题所在。

在单个用户帐户下对此进行测试可以正常工作。我可以启动我的应用程序,它反过来启动原型,如果我启动我的应用程序的第二个实例,第一个实例会在第二个实例重新启动原型的另一个实例之前杀死原型的初始实例。

但是,如果我尝试从两个不同的用户帐户执行此操作,它将失败(静默)。如果我

    启动
  1. 我的应用程序的实例,它启动原型
  2. 切换用户
  3. 启动我的应用程序的实例,然后启动没有我的应用程序的原型 从步骤 1 首先关闭现有的实例。

任何人都可以看到我的代码有什么问题吗?我应该如何在同一台计算机上的多个同时用户会话中使用 EventWaitHandle?

总是这样吗,写完一个长问题几分钟后,答案就会跃入脑海!

我以 EventWaitHandle 的名义错误地使用了斜杠。例如,替换构造函数调用:

new EventWaitHandle(false, EventResetMode.AutoReset, "Global/AaltoTokensAppShutdownEvent", out createdShutdown, security)

有了这个:

new EventWaitHandle(false, EventResetMode.AutoReset, @"GlobalAaltoTokensAppShutdownEvent", out createdShutdown, security)

解决了我的问题。

相关内容

  • 没有找到相关文章

最新更新