Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用EventWaitHandle确保跨多个用户的单个实例_C#_User Accounts_Single Instance_Event Wait Handle - Fatal编程技术网

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

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

合作者已经建立了一个原型,使用处理连接到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开始,原型没有我的应用首先关闭现有的 例如

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

    不是一直都是这样吗?在写了一个长问题几分钟后,答案就会跃入我的脑海

    我以EventWaitHandle的名义把斜杠划错了方向。例如,替换构造函数调用:

    new EventWaitHandle(false, EventResetMode.AutoReset, "Global/AaltoTokensAppShutdownEvent", out createdShutdown, security)
    
    关于这一点:

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

    修复了我的问题。

    事件对象不是这里的合适对象,它受到无法解决的竞争条件的影响。使用互斥是一个样板,它有一个构造函数返回createdNew bool,告诉你你的进程首先到达那里。谢谢,这很有趣。我认为在这种情况下,我相对不受竞赛条件的影响,因为启动第二个应用程序的机制需要时间。我开始使用两个互斥体,但换成了事件,我将进一步探讨。