I have an app that has some installer inside I want to reload everything associated to the app therefor I want to restart the process. I've searched and saw the Application.Restart() and it's drawbacks and wondered what's the best way to do what I need - closing the process and restarting it. or if there's any better way to reinitialize all objects.
-
3Can you elaborate on `Restart()`'s drawbacks? It shuts down the app and restarts it in the same context as the original, which seems to be what you want. – Frédéric Hamidi Jul 24 '11 at 09:23
3 Answers
I would start a new instance and then exit the current one:
private void Restart()
{
Process.Start(Application.ExecutablePath);
//some time to start the new instance.
Thread.Sleep(2000);
Environment.Exit(-1);//Force termination of the current process.
}
private static void Main()
{
//wait because we maybe here becuase of the system is restarted so give it some time to clear the old instance first
Thread.Sleep(5000);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(...
}
Edit: However you should also consider adding some sort of mutex to allow only one instance of the application to run at time, Like:
private const string OneInstanceMutexName = @"Global\MyUniqueName";
private static void Main()
{
Thread.Sleep(5000);
bool firstInstance = false;
using (System.Threading.Mutex _oneInstanceMutex = new System.Threading.Mutex(true, OneInstanceMutexName, out firstInstance))
{
if (firstInstance)
{
//....
}
}
}

- 15,906
- 7
- 45
- 68
-
1Instead of Thread.Sleep, You should instead kill all procesess running the same executable as yourself (that are not yours) in the Main – sternr Jul 24 '11 at 09:37
-
@sternr: I added `mutex` to the code so only one instance is allowed to running at a time. – Jalal Said Jul 24 '11 at 09:39
-
1
-
Of course I am sure, Named `Mutex` and `Semaphores` are shared among processes, note that also my named mutex use `Global\` at the beginning of the name, so It will be work even for the sessions. – Jalal Said Jul 24 '11 at 09:54
-
2If your first app stays in memory a bit longer (for any reason) until your second instance wakes up, both of them will exit. But solving a race condition using `Thread.Sleep` is not a solution. I would be annoyed by an application which hangs for 5s every time I start it. And the "Global\" prefix only makes a difference if your server is running Terminal Services. – vgru Jul 24 '11 at 09:55
-
@Groo: you are right, and that is why I am using `Envirunment.Exit` It will kill the process instantly. Note also that the 5 seconds interval can be trimmed to 3 or so.. – Jalal Said Jul 24 '11 at 09:57
-
-
In my WPF application (single instance by a mutex), I use Process.Start with a ProcessStartInfo, which send a timed cmd command to restart the app:
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C ping 127.0.0.1 -n 2 && \"" + Application.GetCurrentProcess()+ "\"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
ShellView.Close();
The command is sent to the OS, the ping pauses the script for 2-3 seconds, by which time the application has exited from ShellView.Close(), then the next command after the ping starts it again.
Note: The \" puts quotes around the path, incase it has spaces, which cmd can't process without quotes. (My code references this answer)
-
Using a ping command to delay something? I might have gone for a Thread.sleep in stead. Principle of Least Astonishment and all that. If your process takes hold of resources that need to be released before the new instance can take over, then pass an argument instructing the new instance to hold off for a few seconds before attempting to claim those resources. – LOAS Mar 16 '18 at 09:13
-
I used to delay things on the command line using ping, but then I found 'timeout' – Daniel Mošmondor Sep 26 '20 at 08:06
I think starting a new process and closing the existing process is the best way. In this way you have the ability to set some application state for the existing process in between starting and closing processes.
This thread discusses why Application.Restart()
may not work in some cases.
System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
// Set any state that is required to close your current process.
Application.Current.Shutdown();
Or
System.Diagnostics.Process.Start(Application.ExecutablePath);
// Set any state that is required to close your current process.
Application.Exit();
-
If you closes the current process. the System can't reach the `Process.Start`, you should start new instance first and then close the current one. – Jalal Said Jul 24 '11 at 09:40
-
The reason for the downvote was because he wanted to restart the current process, which your answer doesnt – Oskar Kjellin Jul 25 '11 at 18:44
-
1As @jalal said. You first kill the process, then start the new one. Killing yourself will make you not being able to start the process. A killed process cannot start new processes – Oskar Kjellin Jul 26 '11 at 21:53