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?
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();
Je l'ai utilisé avec succès dans WPF:
System.Windows.Forms.Application.Restart();
System.Windows.Application.Current.Shutdown();
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.
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.
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.
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();
Application.Restart();
Process.GetCurrentProcess().Kill();
travailler comme un charme pour moi
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
}