96

How can I restart a WPF Application? In windows Forms I used

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

How to do it in WPF?

razlebe
  • 7,134
  • 6
  • 42
  • 57
Hooch
  • 28,817
  • 29
  • 102
  • 161
  • 4
    Possible duplicates: http://stackoverflow.com/questions/3895188/restart-my-application-using-c, http://stackoverflow.com/questions/1225406/if-wpf-app-is-not-responding-then-auto-restart, http://stackoverflow.com/questions/3634439/how-can-i-restart-wpf-application. The consensus is there's no exact duplicate of the WinForms way, and all of the "solutions" smell slightly hacky. I suspect that's because you generally shouldn't ever have a need to do this, except during debugging. – Cody Gray - on strike Jan 23 '11 at 14:18
  • @Cody Gray Now I'm calling again those methods that are being called on star of application. It works good. But for other application I have to restart application. – Hooch Jan 24 '11 at 09:24
  • 3
    @Cody Gray Why do you say one should never need this? There are lots of reasons why an application might need to be restarted, why force the user to re-run the executable when you can do that for them? – epalm Mar 10 '11 at 21:13
  • 1
    @epalm: That's just it: I can't think of a single reason why an application might need to be restarted, except during debugging. *Maybe* if you've automatically downloaded and installed updates, but that should probably be done with a separate updater app, should probably happen only at startup/shutdown, and should let the user decide whether or not they want to continue working in the app (a la Firefox and Chrome). – Cody Gray - on strike Mar 11 '11 at 00:37
  • 4
    @Cody Gray - Here's one example (unless you can give me a better way to do this). We're running an app that uses WPF to connect to a server. It discovers the server, then uses that discovery information to write the client config. The app can't use this info until it's restarted, so after downloading the config, we have to restart. – Dirk Dastardly Feb 07 '13 at 14:52
  • @Drew, or you could reload the [ConfigurationManager](http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx). – Tom Padilla Aug 01 '13 at 18:52

8 Answers8

124

I found this: It works. But. Is there any better way?

System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
Application.Current.Shutdown();
Hooch
  • 28,817
  • 29
  • 102
  • 161
  • 1
    @AndreiRinea No. But just save them at start and pass them as arguments to this function call. It is easy. – Hooch Aug 09 '12 at 18:30
  • 19
    Note that you don't want to use this method if your application is deployed with ClickOnce. The `ApplicationDeployment.IsNetworkDeployed` will be false when you restart. See http://bit.ly/RKoVBz for more info. If your application is not deployed with ClickOnce, this method works great. – blachniet Oct 21 '12 at 14:17
  • @blachniet Thanks. Took note of it. – Hooch Aug 01 '14 at 09:44
  • @blachniet, what would be the effect to my application if `ApplicationDeployment.IsNetworkDeployed` is false? – Mark Sep 03 '15 at 03:57
  • 1
    @ChristianMark, it may have no effect. It depends on your application. I have worked on some apps in the past that had both ClickOnce and normal installer deployments, and some parts of them behaved differently based on whether or not `ApplicationDeployment.IsNetworkDeployed` was true. For example, if you are ClickOnce deployed within an organization, you might then be able to infer that you should have access to organization network resources (file shares, email servers, etc.). – blachniet Sep 03 '15 at 12:05
  • Ahhh.. I see. Though my question is the possible code-level effect of this. Nevertheless, it worked.:) I do deploy my application only for organization network so I think it is not really an issue. I only use a shared database. File shares/emails doesn't really matter. – Mark Sep 04 '15 at 00:00
  • pretty freaking awesome! – Sandepku May 08 '16 at 16:53
  • 3
    if you want to preserve Command-line args , you can get them first from `Environment.GetCommandLineArgs()` then pass them to the Process.Start method – Ahmed Fwela May 08 '17 at 09:08
  • Terrific! That's all I needed. – Eric Z Nov 19 '17 at 06:16
  • @blachniet You should definitly post this answer in a case of an ClickOnce deployment. – Matthieu Charbonnier Aug 27 '18 at 14:00
  • This didn't work for me until I change the location to .exe as in Application.ResourceAssembly.Location.Replace(".dll",".exe") – Mark Sep 15 '21 at 10:47
48

I've used this in WPF, successfully:

System.Windows.Forms.Application.Restart();
System.Windows.Application.Current.Shutdown();
epalm
  • 4,283
  • 4
  • 43
  • 65
18

Runs a new instance of the program by command line after 1 second delay. During the delay current instance shutdown.

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

EDIT:

I fixed the code:

instead of: Assembly.GetExecutingAssembly().Location

this: Assembly.GetEntryAssembly().Location

This is important when the function runs in a separate dll.

And -

instead of: Application.Current.Shutdown();

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

It will work both in WinForms and in WPF and if you write a dll that is designed for both then it is very important.

16
Application.Current.Shutdown();
System.Windows.Forms.Application.Restart();

In this order worked for me, the other way around just started another instance of the app.

Jraco11
  • 4,526
  • 3
  • 20
  • 20
12
Application.Restart();

or

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

In my program I have a mutex to ensure only one instance of the application running on a computer. This was causing the newly started application to not start because the mutex had not been release in a timely fashion. As a result I put a value into Properties.Settings that indicates that the application is restarting. Before calling Application.Restart() the Properties.Settings value is set to true. In Program.Main() I also added a check for that specific property.settings value so that when true it is reset to false and there is a Thread.Sleep(3000);

In your program you may have the logic:

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

That's it.

Pascalsz
  • 1,092
  • 11
  • 10
  • 20
    This answer (marked as answer) is misleading. The original question was about restarting a WPF application much akin to how it was done in WinForms. Unfortunately your answer is still using a WinForms restart (something that's not available in WPF) and also contains examples that are irrelevant to question being asked (like Mutex?). – test-in-prod Jul 09 '14 at 18:05
  • 7
    Maybe misleading for WPF-Only answer but useful in combination with other answers for me because I was needing to restart my WPF which uses a mutex. This does the job. – Sebastien GISSINGER Dec 10 '15 at 00:36
  • Forgetting the issue that it's using WinForms, wouldn't the easiest way to work around the mutex be to just release it before starting the new instance? Anything that relies on Thread.Sleep to work probably should be rethought. – Jamie Aug 18 '23 at 22:23
5

These proposed solutions may work, but as another commenter has mentioned, they feel kind of like a quick hack. Another way of doing this which feels a little cleaner is to run a batch file which includes a delay (e.g. 5 seconds) to wait for the current (closing) application to terminate.

This prevents the two application instances from being open at the same time. In my case its invalid for two application instances to be open at the same time - I'm using a mutex to ensure there is only one application open - due to the application using some hardware resources.

Example windows batch file ("restart.bat"):

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

And in the WPF application, add this code:

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

// Close the current application
Application.Current.MainWindow.Close();
dodgy_coder
  • 12,407
  • 10
  • 54
  • 67
  • 12
    Writing a batch file with a sleep just feels like a long hack but possibly worse. – Philliproso Oct 22 '13 at 19:34
  • @Philliproso agreed, it is a hack, at the time I needed a completely new windows process for the restarted application, which the other methods here I believe do not provide, but this one does. – dodgy_coder Sep 06 '16 at 05:57
  • Or just release the mutex before you start the new instance. – Jamie Aug 18 '23 at 22:24
3
 Application.Restart();
 Process.GetCurrentProcess().Kill();

work like a charm for me

abrfra
  • 634
  • 2
  • 6
  • 24
  • 1
    This helped me avoid one simple issue, my startup args, my app crashed on any restart method I tried while this one kept things safe. Thank you :) – JustADev Jul 17 '14 at 22:29
  • 7
    Where do you get restart from? System.Windows.Application does not have a Restart method – usefulBee Nov 17 '15 at 17:33
1

Taking Hooch's example, I used the following:

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 
}
breen
  • 51
  • 4