web-dev-qa-db-fra.com

Comment redémarrer une application WPF?

Comment puis-je redémarrer une application WPF? Dans les formulaires Windows que j'ai utilisés

System.Windows.Forms.Application.Restart();

Comment le faire dans WPF?

72
Hooch

J'ai trouvé ceci: ça marche. Mais. Y a-t-il une meilleure façon?

System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
Application.Current.Shutdown();
91
Hooch

Je l'ai utilisé avec succès dans WPF:

System.Windows.Forms.Application.Restart();
System.Windows.Application.Current.Shutdown();
35
epalm
Application.Restart();

ou

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

Dans mon programme, j'ai un mutex pour garantir qu'une seule instance de l'application s'exécute sur un ordinateur. Cela empêchait la nouvelle application de démarrer car le mutex n'avait pas été libéré en temps opportun. Par conséquent, j'ai mis une valeur dans Properties.Settings qui indique que l'application redémarre. Avant d'appeler Application.Restart (), la valeur Properties.Settings est définie sur true. Dans Program.Main (), j'ai également ajouté une vérification pour cette valeur spécifique de property.settings de sorte que lorsqu'elle est vraie, elle est réinitialisée sur false et il y a un Thread.Sleep (3000);

Dans votre programme, vous pouvez avoir la logique:

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

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

C'est ça.

10
Pascalsz

Exécute une nouvelle instance du programme par ligne de commande après 1 seconde de retard. Pendant l'arrêt de l'instance de retard actuel.

ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C choice /C Y /N /D Y /T 1 & START \"\" \"" + Assembly.GetEntryAssembly().Location + "\"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
Process.GetCurrentProcess().Kill();

MODIFIER:

J'ai corrigé le code:

au lieu de: Assembly.GetExecutingAssembly().Location

ceci: Assembly.GetEntryAssembly().Location

Ceci est important lorsque la fonction s'exécute dans une DLL distincte.

Et -

au lieu de: Application.Current.Shutdown();

ceci: Process.GetCurrentProcess().Kill();

Cela fonctionnera à la fois dans WinForms et dans WPF et si vous écrivez une DLL conçue pour les deux, elle est très importante.

9
magicode
Application.Current.Shutdown();
System.Windows.Forms.Application.Restart();

Dans cet ordre, cela a fonctionné pour moi, l'inverse vient de démarrer une autre instance de l'application.

7
Jraco11

Ces solutions proposées peuvent fonctionner, mais comme un autre commentateur l'a mentionné, elles se sentent un peu comme un hack rapide. Une autre façon de procéder, qui semble un peu plus propre, consiste à exécuter un fichier de commandes comprenant un délai (par exemple 5 secondes) pour attendre la fin de l'application en cours (fermeture).

Cela empêche les deux instances d'application d'être ouvertes en même temps. Dans mon cas, il est invalide que deux instances d'application soient ouvertes en même temps - j'utilise un mutex pour m'assurer qu'il n'y a qu'une seule application ouverte - car l'application utilise certaines ressources matérielles.

Exemple de fichier batch Windows ("restart.bat"):

sleep 5
start "" "C:\Dev\MyApplication.exe"

Et dans l'application WPF, ajoutez ce code:

// Launch the restart batch file
Process.Start(@"C:\Dev\restart.bat");

// Close the current application
Application.Current.MainWindow.Close();
2
dodgy_coder
 Application.Restart();
 Process.GetCurrentProcess().Kill();

travailler comme un charme pour moi

1
abrfra

En prenant l'exemple de Hooch, j'ai utilisé ce qui suit:

using System.Runtime.CompilerServices;

private void RestartMyApp([CallerMemberName] string callerName = "")
{
    Application.Current.Exit += (s, e) =>
    {
        const string allowedCallingMethod = "ButtonBase_OnClick"; // todo: Set your calling method here

        if (callerName == allowedCallingMethod)
        {
            Process.Start(Application.ResourceAssembly.Location);
        }
     };

     Application.Current.Shutdown(); // Environment.Exit(0); would also suffice 
}
0
breen