... not being fluent with IL, ...
Have you considered using a decompiler (Reflector, dotPeek) or, even better, the reference source code of the .NET framework?
Anyway.
At a casual look it does the following:
In all below cases, the current instance is terminated using Application.ExitInternal()
. That is the gist of the public Application.Exit()
method, eliding some security checks/asserts.
See if it can determine the Assembly.GetEntryAssembly()
. If that is null
the call the Application.Restart()
was most likely done from unmanaged code and the operation throws a NotSupportedException
to the caller.
See if the current process is ieexec.exe
, if so use it to restart the application (for more information about ieexec.exe
see here). Actually that is pretty much also a Process.Start()
call to ieexec.exe
, but the command line arguments are not gathered by Environment.GetCommandLineArgs()
(see below), but by reading the APP_LAUNCH_URL
application domain data.
See if the application is a click-once application (ApplicationDeployment.IsNetworkDeployed
), if so call an CLR internal native code to (re)launch that: CorLauncApplication
. The only publicly available source code that somewhat resembles the native parts of the CLR is the shared source CLI (sscli), which is based on the .NET 2.0 framework and also is partly incomplete. It contains a definition for that function (clr\src\vm\hosting.cpp
), but it is only a stub. In the end it will use some means to restart the process (e.g. Win32's CreateProcess
API).
Else: the application is a "regular" .NET application. Environment.GetCommandLineArgs()
is used to recreate the original command line and Process.Start(Application.ExecutablePath)
is used to restart the application.
The use of the Application.Exit
-mechanism to try to end the current instance is probably the reason why you find it unreliable. Forms that cancel the send closing event can interrupt it. Also see this SO question.