Handle multiple context menu selections - Fixes #770

The problem is that multiple context menu selections spawn multiple .exe
(invoked). Each invoked .exe sets the InstanceProxy variables in the
running .exe and tells it to start a thread to process. But, there is no
waiting, so the InstanceProxy variables get clobbered before they can
get used.
This fix uses a semaphore to control the invoked .exe. There is only one
entry allowed forcing invoked .exe to wait until any other invoked .exe
is finished running and releases the semaphore.
This commit is contained in:
Brian 2016-03-03 18:57:21 -05:00
parent d942099e12
commit c21036aa0e

View file

@ -34,10 +34,13 @@ namespace SingleInstanceApplication
{
public static class ApplicationInstanceManager
{
private static Semaphore semaphore;
[DebuggerStepThrough]
public static bool CreateSingleInstance(string name, EventHandler<InstanceCallbackEventArgs> callback, string[] args)
{
string eventName = string.Format("{0}-{1}", Environment.MachineName, name);
string semaphoreName = string.Format("{0}{1}", eventName, "Semaphore");
InstanceProxy.IsFirstInstance = false;
InstanceProxy.CommandLineArgs = args;
@ -46,9 +49,13 @@ public static bool CreateSingleInstance(string name, EventHandler<InstanceCallba
{
using (EventWaitHandle eventWaitHandle = EventWaitHandle.OpenExisting(eventName))
{
semaphore = Semaphore.OpenExisting(semaphoreName);
semaphore.WaitOne();
UpdateRemoteObject(name);
if (eventWaitHandle != null) eventWaitHandle.Set();
semaphore.Release();
}
Environment.Exit(0);
@ -59,6 +66,7 @@ public static bool CreateSingleInstance(string name, EventHandler<InstanceCallba
using (EventWaitHandle eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName))
{
semaphore = new Semaphore(1, 1, semaphoreName);
ThreadPool.RegisterWaitForSingleObject(eventWaitHandle, WaitOrTimerCallback, callback, Timeout.Infinite, false);
}
@ -107,6 +115,7 @@ private static void RegisterRemoteType(string uri)
process.Exited += delegate
{
ChannelServices.UnregisterChannel(serverChannel);
semaphore.Close();
};
}