Application.Restart () + conflicto de instancia única en la aplicación de Windows

Hola amigos,

Tengo una aplicación de Windows donde controlo una sola instancia.

Cuando esta aplicación se actualice con clickonce, la aplicación se reiniciará después de aplicar las actualizaciones.

La aplicación se reinicia pero no puede continuar como, IsFirstInstance = condición falsa.

Pero la documentación de Application.Restart () dice que cierra la aplicación en ejecución y crea una nueva instancia.

La clase de instancia única se da a continuación:

 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;

/// <summary>
/// Application Instance Manager
/// </summary>
public static class ApplicationInstanceManager
{
    /// <summary>
    /// Creates the single instance.
    /// </summary>
    /// <param name="name">The name.</param>
    /// <param name="callback">The callback.</param>
    /// <returns></returns>
    public static bool CreateSingleInstance(string name, EventHandler<InstanceCallbackEventArgs> 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;
    }

    /// <summary>
    /// Updates the remote object.
    /// </summary>
    /// <param name="uri">The remote URI.</param>
    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);
    }

    /// <summary>
    /// Registers the remote type.
    /// </summary>
    /// <param name="uri">The URI.</param>
    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); };
    }

    /// <summary>
    /// Wait Or Timer Callback Handler
    /// </summary>
    /// <param name="state">The state.</param>
    /// <param name="timedOut">if set to <c>true</c> [timed out].</param>
    private static void WaitOrTimerCallback(object state, bool timedOut)
    {
        // cast to event handler
        EventHandler<InstanceCallbackEventArgs> callback = state as EventHandler<InstanceCallbackEventArgs>;
        if (callback == null) return;

        // invoke event handler on other process
        callback(state,
                 new InstanceCallbackEventArgs(InstanceProxy.IsFirstInstance,
                                               InstanceProxy.CommandLineArgs));
    }
}

}

aquí:

try { // Try opening existing wait handle eventWaitHandle = EventWaitHandle.OpenExisting(eventName); } catch(Exception ex) { // Got exception = handle wasn't created yet InstanceProxy.IsFirstInstance = true; }

no se lanza ninguna excepción. Por lo tanto, como puede ver en el código, saldrá de Environment.Exit (0).

Respuestas a la pregunta(0)

Su respuesta a la pregunta