这个问题并不是关于如何重新启动一个应用程序。我已经通过使用Mutex和辅助启动器应用程序来实现了。在使用Application.Restart遇到一些问题后,我不得不采取这种方式。
无论如何,由于我不熟悉IL,我想知道是否有人可以解释一下Application.Restart的工作原理。它调用运行时,但运行时具体做了什么呢?它如何关闭现有实例,并如何知道何时启动新实例?
...不熟悉IL...
您是否考虑使用反编译工具(Reflector,dotPeek)或者更好的方法是使用.NET框架的参考源代码?
无论如何。
初步看来它执行以下操作:
在以下所有情况下,当前实例均使用Application.ExitInternal()
终止。这是公共Application.Exit()
方法的要点,省略了一些安全检查/断言。Assembly.GetEntryAssembly()
。如果为null
,则调用Application.Restart()
很可能是从非托管代码中完成的,并且该操作会向调用者抛出NotSupportedException
。ieexec.exe
,如果是,则使用它重新启动应用程序(有关ieexec.exe
的更多信息,请参见here)。实际上,这几乎也是对ieexec.exe
进行Process.Start()
调用,但是命令行参数不是通过Environment.GetCommandLineArgs()
(请参见下文)收集的,而是通过读取APP_LAUNCH_URL
应用程序域数据收集的。ApplicationDeployment.IsNetworkDeployed
),如果是,则调用CLR内部本机代码来(重新)启动它:CorLauncApplication
。唯一公开可用的与CLR本机部分相似的源代码是共享源CLI(sscli),它基于.NET 2.0框架,也部分不完整。它包含该函数的定义(clr\src\vm\hosting.cpp
),但它只是一个存根。最终将使用某种方法重新启动进程(例如Win32的CreateProcess
API)。Environment.GetCommandLineArgs()
重新创建原始命令行,并使用Process.Start(Application.ExecutablePath)
重新启动应用程序。Application.Exit
机制尝试结束当前实例可能是您发现其不可靠的原因。取消发送关闭事件的窗体可能会中断它。还请参见 this SO 问题。
Process.Start(Application.ExecutablePath)
? - joeApplication.Restart()
的线程是最后执行的事情。 - Scott ChamberlainApplication.Restart()
,实际上这种用例在MSDN页面上有说明)。但是对于大多数情况,我会使用单独的更新器存根应用程序来完成。 - Scott Chamberlain