0

合作者使用 Processing 构建了一个原型,该原型连接到 Sparkfun RFID 阅读器,我认为使用的是通过 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:\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)没有代码可以响应同时启动的大量实例,一次只有两个。但这不是我的问题是关于。)

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

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

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

谁能看到我的代码有什么问题?我应该如何在同一台机器上的多个同时用户会话中使用 EventWaitHandle?

4

1 回答 1

0

不总是这样吗,写了一个长问题后几分钟,答案就会浮现在脑海!

我以 EventWaitHandle 的名义弄错了斜线。例如替换构造函数调用:

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

有了这个:

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

解决了我的问题。

于 2012-08-08T10:37:46.130 回答