Соавторы создали прототип, используя 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, сначала отключив существующий экземпляр.
Может ли кто-нибудь увидеть, что не так с моим кодом? Как мне использовать EventWaitHandle для нескольких одновременных пользовательских сеансов на одном компьютере?