0

共同編集者は、SparkfunRFIDリーダーに接続するProcessingを使用してプロトタイプを作成しました。USB経由のシリアル接続を使用していると思います。私たちはプロトタイプを多くのトライアリストの家に配備しましたが、私が愚かに見落としていた一般的な使用シナリオの1つは、ユーザーの切り替えでした。したがって、プロトタイプアプリケーションの1つのインスタンスのみがマシン上のすべてのユーザーで実行されるようにするラッパーを作成しています。

シンプルなコンソールアプリとして、これを最初に試しています。コードは次のとおりです。

    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)同時に開始する多数のインスタンスに応答するコードがないこと(一度に2つだけ)に問題があることを知っています。しかし、それは私のものではありません。質問についてです。)

単一のユーザーアカウントでこれをテストすると、正常に機能します。アプリを起動すると、プロトタイプが起動します。アプリの2番目のインスタンスを起動すると、最初のインスタンスがプロトタイプの最初のインスタンスを強制終了してから、2番目のインスタンスがプロトタイプの別のインスタンスを新たに起動します。

しかし、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 に答える