Application.Restart () + конфликт отдельных экземпляров в приложении Windows
Привет, друзья,
У меня есть приложение для Windows, где я контролирую один экземпляр.
Когда это приложение обновляется с помощью clickonce, приложение будет перезапущено после применения обновлений.
Приложение перезапускается, но не может продолжить работу, IsFirstInstance = ложное условие.
Но в документации Application.Restart () говорится, что он закрывает запущенное приложение и создает новый экземпляр.
Класс одного экземпляра приведен ниже:}
using System;
using System.Diagnostics;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Threading;
using agent_common_plugin_sdk;
///
/// Application Instance Manager
///
public static class ApplicationInstanceManager
{
///
/// Creates the single instance.
///
/// The name.
/// The callback.
///
public static bool CreateSingleInstance(string name, EventHandler callback)
{
EventWaitHandle eventWaitHandle = null;
string eventName = string.Format("{0}-{1}", Environment.MachineName, name);
InstanceProxy.IsFirstInstance = false;
InstanceProxy.CommandLineArgs = Environment.GetCommandLineArgs();
try
{
// Try opening existing wait handle
eventWaitHandle = EventWaitHandle.OpenExisting(eventName);
}
catch(Exception ex)
{
// Got exception = handle wasn't created yet
InstanceProxy.IsFirstInstance = true;
}
if (InstanceProxy.IsFirstInstance)
{
// init handle
eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName);
// register wait handle for this instance (process)
ThreadPool.RegisterWaitForSingleObject(eventWaitHandle, WaitOrTimerCallback, callback, Timeout.Infinite, false);
eventWaitHandle.Close();
// register shared type (used to pass data between processes)
RegisterRemoteType(name);
}
else
{
// pass console arguments to shared object
UpdateRemoteObject(name);
// invoke (signal) wait handle on other process
if (eventWaitHandle != null) eventWaitHandle.Set();
// kill current process
Environment.Exit(0);
}
return InstanceProxy.IsFirstInstance;
}
///
/// Updates the remote object.
///
/// The remote URI.
private static void UpdateRemoteObject(string uri)
{
// register net-pipe channel
IpcClientChannel clientChannel = new IpcClientChannel();
ChannelServices.RegisterChannel(clientChannel, true);
// get shared object from other process
InstanceProxy proxy =
Activator.GetObject(typeof(InstanceProxy),
string.Format("ipc://{0}{1}/{1}", Environment.MachineName, uri)) as InstanceProxy;
// pass current command line args to proxy
if (proxy != null)
proxy.SetCommandLineArgs(InstanceProxy.IsFirstInstance, InstanceProxy.CommandLineArgs);
// close current client channel
ChannelServices.UnregisterChannel(clientChannel);
}
///
/// Registers the remote type.
///
/// The URI.
private static void RegisterRemoteType(string uri)
{
// register remote channel (net-pipes)
IpcServerChannel serverChannel = new IpcServerChannel(Environment.MachineName + uri);
ChannelServices.RegisterChannel(serverChannel, true);
// register shared type
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(InstanceProxy), uri, WellKnownObjectMode.Singleton);
// close channel, on process exit
Process process = Process.GetCurrentProcess();
process.Exited += delegate { ChannelServices.UnregisterChannel(serverChannel); };
}
///
/// Wait Or Timer Callback Handler
///
/// The state.
/// if set to true [timed out].
private static void WaitOrTimerCallback(object state, bool timedOut)
{
// cast to event handler
EventHandler callback = state as EventHandler;
if (callback == null) return;
// invoke event handler on other process
callback(state,
new InstanceCallbackEventArgs(InstanceProxy.IsFirstInstance,
InstanceProxy.CommandLineArgs));
}
}
Вот:
try { // Try opening existing wait handle eventWaitHandle = EventWaitHandle.OpenExisting(eventName); } catch(Exception ex) { // Got exception = handle wasn't created yet InstanceProxy.IsFirstInstance = true; }
не исключение бросается. Следовательно, как вы можете видеть в коде, он выйдет из Environment.Exit (0).