it-swarm.com.de

Warum ist Application.Restart () nicht zuverlässig?

Mit der Methode Application.Restart() in C # sollte die aktuelle Anwendung neu gestartet werden. Dies scheint jedoch nicht immer zu funktionieren.

Gibt es einen Grund für diese Ausgabe? Kann mir jemand sagen, warum es nicht immer funktioniert?

42
MADMap

Dafür kann es viele Gründe geben. Es ist nicht so, dass die Methode nicht funktioniert; Oft vergessen Programmierer jedoch, dass sie etwas in ihren Code eingefügt haben, durch das die Anwendung nicht automatisch heruntergefahren oder gestartet werden kann. Zwei Beispiele:

  • Das Closing-Ereignis in einem Formular kann das Herunterfahren einer App stoppen
  • Wenn Sie nach einem bereits laufenden Prozess suchen, wird der alte Prozess möglicherweise nicht schnell genug geschlossen, damit der neue Prozess gestartet werden kann.

Überprüfen Sie Ihren Code für solche Fallstricke. Wenn dieses Verhalten in einer leeren Anwendung auftritt, liegt das Problem wahrscheinlich eher bei der eigentlichen Funktion als beim Code.

Überprüfen Sie den Microsoft-Quellcode von application restart .

27
TheSmurf

In meinem Fall (KEINE Einzelinstanz), wo

Application.Restart();

hat nicht funktioniert

System.Diagnostics.Process.Start(Application.ExecutablePath);
Application.Exit();

hat den Job gemacht!

18
cprcrack

Das einzige Mal, dass ich mit dieser Art von Problem konfrontiert bin, ist, dass ich in meinem Hauptformular einen benutzerdefinierten FormClosing-Ereignishandler hatte, der die Logik durchführte und das Ereignis abbrach.

BEARBEITEN:

Ich bin jetzt auf eine andere Instanz gestoßen und aufgrund Ihrer Kommentare spiegelt sie möglicherweise das wider, was Sie erlebt haben. 

Beim Ausführen einer Einzelinstanzanwendung mit einem Mutex rief ich Application.Restart() von einem ziemlich eingebetteten Ort aus an, der viel zu bereinigen hatte. Es scheint also, dass beim Neustart eine neue Instanz gestartet wurde, bevor die vorherige Instanz abgeschlossen war. Daher verhinderte der Mutex, dass die neue Instanz gestartet wurde.

7
Timothy Carter

In meinem Programm habe ich einen Mutex, um sicherzustellen, dass nur eine Instanz der Anwendung auf einem Computer ausgeführt wird. Dies führte dazu, dass die neu gestartete Anwendung nicht gestartet wurde, da der Mutex nicht rechtzeitig freigegeben wurde. Als Ergebnis habe ich in Properties.Settings einen Wert eingegeben, der angibt, dass die Anwendung neu gestartet wird. Vor dem Aufruf von Application.Restart() wird der Wert Properties.Settings auf true gesetzt. In Program.Main() habe ich auch eine Überprüfung für diesen bestimmten property.settings -Wert hinzugefügt, sodass, wenn true auf false zurückgesetzt wird und es eine Thread.Sleep(3000); gibt.

In Ihrem Programm haben Sie möglicherweise die Logik:

if (ShouldRestartApp)
{
   Properties.Settings.Default.IsRestarting = true;
   Properties.Settings.Default.Save();
   Application.Restart();
}

In Program.Main()

[STAThread]
static void Main()
{
   Mutex runOnce = null;

   if (Properties.Settings.Default.IsRestarting)
   {
      Properties.Settings.Default.IsRestarting = false;
      Properties.Settings.Default.Save();
      Thread.Sleep(3000);
   }

   try
   {
      runOnce = new Mutex(true, "SOME_MUTEX_NAME");

      if (runOnce.WaitOne(TimeSpan.Zero))
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new Form1());
      }
   }
   finally
   {
      if (null != runOnce)
         runOnce.Close();
   }
}

Das ist es.

6
cmptrs4now

Versuchen Sie das Sperren vor dem Ablegen. So initiiere ich einen vollständigen App-Dump. Könnte für Sie arbeiten, vielleicht nicht.

Context.Application.Lock();
Context.Session.Abandon();
Context.Application.RemoveAll();
Context.Application.Restart();
Context.Application.UnLock();
2
Oli

Wenn die Anwendung zuerst von einem Netzwerkspeicherort aus gestartet wurde und nicht signiert ist (Sie erhalten zuerst den Warndialog), wird sie nicht neu gestartet und nur beendet.

1
Matt Hanson
Application.Restart();
Application.ExitThread();                                                     

das hat für mich gedankt.

1
shima lagzian

Versuchen Sie diesen Code:

bool appNotRestarted = true;

Dieser Code muss auch in der Funktion enthalten sein:

if (appNotRestarted == true)
{
    appNotRestarted = false;
    Application.Restart();
    Application.ExitThread();
}
1
ferhatayhan

Ich weiß, dass dies ein alter Thread ist, aber ich habe eine Problemumgehung gefunden. Hoffentlich hilft dies jemand anderen in Not. 

Ich brauchte eine Lösung, die die Aktualisierungssequenz während des Starts einer ClickOnce-Anwendung vom Code auslöste. Applicatoin.Restart hat das nicht getan. Ich wollte eine Möglichkeit, nach einem Update zu suchen und dann den integrierten Update-Manager aufzurufen, sodass ich kein benutzerdefiniertes Update schreiben musste.

    'VB Code Sample
    Dim strStart As String = System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) & "\Programs\Folder\YourApplication.appref-ms"
    Application.Exit()
    Try
        Process.Start(strStart)
    Catch ex As Exception
        'Do something with the exception
    End Try

Das einzige Problem, das ich bei dieser Problemumgehung sehe, ist, dass ein Benutzer die Verknüpfung aus dem Startmenü löschen könnte. Wenn dies ein Problem ist, können Sie Code schreiben, um den Startmenü-Link in einen Ordner Ihrer Wahl zu kopieren, vorzugsweise im Anwendungsordner von ClickOnce. Dies ist wichtig, da das Startmenüsymbol für Ihre Anwendung keine .lnk- oder .exe-Datei ist. Es handelt sich tatsächlich um eine .appref-ms-Verknüpfung. Siehe ClickOnce .appref-ms mehr als eine Verknüpfung zu einer Anwendungsdatei. Dieser Link erklärt das genauer.

Dieser Code funktioniert mit ClickOnce SingleInstance-Anwendungen.

0
Nathan
public static void ApplicationRestart(params string[] commandLine)
    {
        lock (SynchObj)
        {
            if (Assembly.GetEntryAssembly() == null)
            {
                throw new NotSupportedException("RestartNotSupported");
            }

            if (_exiting)
                return;

            _exiting = true;

            if (Environment.OSVersion.Version.Major < 6) return;

            bool cancelExit = true;

            try
            {
                foreach (Form f in Application.OpenForms.OfType<Form>().ToList())
                {
                    f.InvokeIfRequired(frm =>
                    {
                        frm.FormClosing += (sender, args) => cancelExit = args.Cancel;
                        frm.Close();
                    });

                    if (cancelExit) break;
                }

                if (cancelExit) return;

                Process.Start(new ProcessStartInfo
                {
                    UseShellExecute = true,
                    WorkingDirectory = Environment.CurrentDirectory,
                    FileName = Application.ExecutablePath,
                    Arguments = commandLine.Length > 0 ? string.Join(" ", commandLine) : string.Empty
                });

                Application.Exit();
            }
            finally
            {
                _exiting = false;
            }
        }
    }
0

Ich habe dasselbe Problem mit dem .NET 4.7 Framework. Die akzeptierte Antwort war der Schlüssel für meinen Erfolg. Ich hatte Code im FormClosing-Ereignis, das einige Zeit in Anspruch nahm und den Neustartprozess anhielt.

If JustCloseIT = False Then
   'all closing code, like logging the session log-out to a database and all those goodies we all do.
 End If

nur dann hat das Application.Restart () funktioniert!

0
Nandostyle