What's equivalent in WPF for "Application.Restart()" in WindowsForms?
-
Tuesday, September 19, 2006 12:56 PMApplication.Curent object doesn't contain such method.
Any suggestions?
Thanks
All Replies
-
Tuesday, September 19, 2006 5:06 PMModerator
Afaik, there isn't one in WPF. -
Tuesday, September 19, 2006 5:37 PMWhy a such method has been omitted in WPF?
It's very useful for ClickOnce (after an update) or a language change...
There is absolutly no alternative?
Thanks -
Thursday, March 15, 2007 4:10 PMIs there going to be one? Or equivalent functionality? How are you supposed to 'refresh' the application following a ClickOnce update?
Thanks
Nick -
Friday, March 16, 2007 12:04 AMThis feature may be added later on, but Application.Restart() is not hard to implement for your application. Use Reflector to see the WinForms implementation. ;-)
-
Tuesday, November 06, 2007 8:51 AMAs it turns out, Application.Restart() is quite hard to implement properly, as evidenced by using Reflector to inspect the WinForms implementation and discovering that it isn't actually implemented properly there, for a start. It completely ignores command line escaping when creating the command line to start the new process with. To demonstrate this, you can use some very short code just to show command args and perform a restart:
static void Main(string[] args)
{
Console.WriteLine("Restart Tester");
Console.WriteLine("command line: " + Environment.CommandLine);
Console.WriteLine("args:");
foreach (string arg in args)
Console.WriteLine("\t" + arg);
Console.WriteLine();
Console.WriteLine("Enter r to restart, or anything else to quit");
if(Console.ReadLine() == "r")
{
Application.Restart();
}
}
Open up a command prompt, and run: RestartTest.exe "te\" st" Due to the (admittedly obscure) command line escaping rules, the result of this is:
command line: RestartTest.exe "te\" st"
args:
te" st
If the application is then restarted using Application Restart, the escaping is ignored, and the restarted instance displays:
command line: "C:\...\RestartTest.exe" "te" st"
args:
te
st
If you want to do Restart properly, it's substantially trickier to get the command line to pass to the next instance. My current code for doing this, which I hope handles all cases, is:
/// <summary>
/// Gets the command args this app was started with, as executed, not parsed into args[]
/// </summary>
public static string GetCommandArgs()
{
string commandLine = Environment.CommandLine;
//Find either the space, which is a the delimeter, or a " mark, which bounds spaces
int pos = 0;
do
{
if (pos >= commandLine.Length)
return String.Empty; //No command line args
pos = commandLine.IndexOfAny(new char[] { ' ', '"' }, pos);
if (pos == -1)
return String.Empty; //No command line args
if (commandLine[pos] == '"')
{
//Find the closing " mark. " marks can't be escaped in path names
pos = commandLine.IndexOf('"', pos + 1) + 1;
if (pos == 0)
{
//No command line args. Probably malformed command line too.
System.Diagnostics.Trace.TraceWarning("Could not find closing \" mark in command line: " + commandLine);
return String.Empty;
}
//Otherwise, go round again to find another quote, or alternatively a space
}
else
{
System.Diagnostics.Debug.Assert(commandLine[pos] == ' ', "Expecting a space here, if not a \" mark");
//Everything past this point should now be the command args, as this is an unquoted space
return commandLine.Substring(pos + 1);
}
} while (true);
}
I hope this helps, and if anyone has further refinements on the above, or notices cases for which it does not work, I'd be interested to hear them.
Alex -
Thursday, July 23, 2009 6:50 PM
As far as I know you could add a reference to System.Windows.Forms and add these code statements:System.Windows.Forms.Application.Restart(); Application.Current.Shutdown();
- Proposed As Answer by Junior Mayhe Thursday, July 23, 2009 6:50 PM
-
Friday, October 02, 2009 10:17 AM
IMO, We should never reference to WIndows.Form.
Better to use the code like that below ....
System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
Application.Current.Shutdown();
Michael Sync: blog: http://michaelsync.net- Proposed As Answer by FedePrado Sunday, January 30, 2011 6:32 AM
-
Thursday, December 17, 2009 4:39 AMMichael SyncThanks for that last answer! That is brilliant!Brenda
-
Thursday, December 17, 2009 4:59 AMI may be wrong, but I'm sure I found that using Process.Start triggered the UAC prompt in Vista, whereas Application.Restart didn't. If that's the case, using Process.Start would not be a viable solution for me and this would be a significant omission by MS to not include an appropriate restart method. In fact I think the Vista logo guidelines expressly state that you should always use Application.Restart to trigger a refresh of your application?
-
Wednesday, February 24, 2010 1:50 PM
For me, the code below seems to work fine. It should ensure that the new instance is started as late as possible in the shutdown-process to prevent problems with single-instance-apps.
Application.Current.Exit += delegate(object sender, ExitEventArgs e)
{
System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
};
Application.Current.Shutdown(); -
Monday, March 01, 2010 5:01 PM
Here is what I did. The only hack was to hard code 0 for hostType.
1. Add these usings:using System.Deployment.Application; using System.Reflection; using System.ComponentModel; using System.Security; using System.Security.Permissions; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution;
2. Add this class:
// Taken from System.Windows.Forms.UnsafeNativeMethods [StructLayout(LayoutKind.Sequential), SuppressUnmanagedCodeSecurity] internal class PROCESS_INFORMATION { public IntPtr hProcess = IntPtr.Zero; public IntPtr hThread = IntPtr.Zero; public int dwProcessId; public int dwThreadId; private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); ~PROCESS_INFORMATION() { this.Close(); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal void Close() { if ((this.hProcess != IntPtr.Zero) && (this.hProcess != INVALID_HANDLE_VALUE)) { CloseHandle(new HandleRef(this, this.hProcess)); this.hProcess = INVALID_HANDLE_VALUE; } if ((this.hThread != IntPtr.Zero) && (this.hThread != INVALID_HANDLE_VALUE)) { CloseHandle(new HandleRef(this, this.hThread)); this.hThread = INVALID_HANDLE_VALUE; } } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] private static extern bool CloseHandle(HandleRef handle); }3. Add this import:
[DllImport("clr.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] internal static extern void CorLaunchApplication(uint hostType, string applicationFullName, int manifestPathsCount, string[] manifestPaths, int activationDataCount, string[] activationData, PROCESS_INFORMATION processInformation);4. Add your Restart() method:
// Originally from System.Windows.Forms.Application, changed to suit needs [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode), SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static void Restart() { if (Assembly.GetEntryAssembly() == null) { throw new NotSupportedException("RestartNotSupported"); } if (ApplicationDeployment.IsNetworkDeployed) { string updatedApplicationFullName = ApplicationDeployment.CurrentDeployment.UpdatedApplicationFullName; Application.Current.Shutdown(); CorLaunchApplication(0, updatedApplicationFullName, 0, null, 0, null, new PROCESS_INFORMATION()); } }HTH
Eric -
Tuesday, March 02, 2010 10:04 PMJust an update, here is what to use for hostType, it makes a difference:
http://msdn.microsoft.com/en-us/library/aa964883.aspx
* Note: I have no formal CS education, so take all advice with caution :) -
Tuesday, June 22, 2010 10:01 AM
For me, the code below seems to work fine. It should ensure that the new instance is started as late as possible in the shutdown-process to prevent problems with single-instance-apps.
Application.Current.Exit += delegate(object sender, ExitEventArgs e)
{
System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
};
Application.Current.Shutdown();
For me event Application.Current.Exit never happen. -
Thursday, December 02, 2010 10:24 AM
public ICommand RestartCommand { get { if (restartCommand == null) { restartCommand = new Command<Window>( window => { window.Close(); window = new Views.MainView(); window.ShowDialog(); }, window => window != null); } return restartCommand; } }
-
Monday, June 04, 2012 1:52 PM
Maledetto il giorno che ho cominciatoun profetto WPF!!
Come al solito si va indietro invece che avanti!
Ma qual'è il motivo per cui non c'è più il restart, qualcuno lo sa??
Ciao
F.
-
Thursday, June 28, 2012 7:19 PM
So WPF is a step backward from winforms just because it's missing the restart method? Naw... I respectfully disagree...Maledetto il giorno che ho cominciatoun profetto WPF!!
Come al solito si va indietro invece che avanti!
Ma qual'è il motivo per cui non c'è più il restart, qualcuno lo sa??
Ciao
F.
Chase
-
Saturday, June 30, 2012 12:32 PMOk, maybe is not a step back, but it's a restart and learn again everything. it's a bit difficult do accept....
-
Wednesday, August 08, 2012 4:49 PM
Sorry but this is akin to saying you should never P/Invoke because if they meant for a managed language to do this function, it would. Call it a hack, but System.Windows.Forms.dll isn't going to be deprecated from .NET so if you're within the .NET ecosystem, feel free to reference it and utilize it. The only reason you shouldn't utilize Application.Restart() is if Process.Start() works better. It is not an end all/be all because Process.Start() fails miserably when you are based on ISingleInstance. Maybe 75% of the time it'll shut down in time to thwart this issue, but that is not an acceptable success rate.IMO, We should never reference to WIndows.Form.
Better to use the code like that below ....
System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
Application.Current.Shutdown();
Michael Sync: blog: http://michaelsync.netEric Rodewald

