Application.Restart () + Single Instance Konflikt in der Windows-Anwendung

Hallo Freunde,

Ich habe eine Windows-Anwendung, in der ich einzelne Instanz steuert.

Wenn diese Anwendung mit clickonce aktualisiert wird, wird die Anwendung nach dem Anwenden von Updates neu gestartet.

Die Anwendung wird neu gestartet, fährt jedoch nicht fort, da IsFirstInstance = false condition.

Die Application.Restart () -Dokumentation besagt jedoch, dass die laufende App heruntergefahren und eine neue Instanz erstellt wird.

Die Einzelinstanzklasse ist unten angegeben:

 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));
    }
}

}

Hier:

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

Es wird keine Ausnahme geworfen. Wie Sie im Code sehen können, wird Environment.Exit (0) beendet.

Antworten auf die Frage(0)

Ihre Antwort auf die Frage