这个问题不是关于如何重新启动应用程序。我已经通过使用 Mutex 和辅助启动器应用程序实现了这一目标。在使用 Application.Restart 遇到一些问题后,我不得不求助于它。
无论如何,我不熟悉 IL,我想知道是否有人可以首先解释 Application.Restart 是如何工作的。这是对运行时的调用,但运行时到底做了什么?它如何关闭现有实例以及如何知道何时启动新实例?
... 不流利使用 IL,...
您是否考虑过使用反编译器(Reflector、dotPeek),或者更好的是 .NET 框架的参考源代码?
反正。
随便看看它执行以下操作:
在以下所有情况下,当前实例都使用 终止Application.ExitInternal()
。这是公共Application.Exit()
方法的要点,省略了一些安全检查/断言。
看看能不能确定Assembly.GetEntryAssembly()
。如果这是null
调用,Application.Restart()
则很可能是从非托管代码完成的,并且该操作NotSupportedException
向调用者抛出 a。
查看当前进程是否为ieexec.exe
,如果是,则使用它重新启动应用程序(有关更多信息,ieexec.exe
请参见此处)。实际上,这几乎也是对 的Process.Start()
调用ieexec.exe
,但命令行参数不是通过Environment.GetCommandLineArgs()
(见下文)收集的,而是通过读取APP_LAUNCH_URL
应用程序域数据来收集的。
查看应用程序是否为单击一次应用程序 ( ApplicationDeployment.IsNetworkDeployed
),如果是,则调用 CLR 内部本机代码以(重新)启动该应用程序CorLauncApplication
:唯一与 CLR 的本机部分有些相似的公开可用源代码是共享源 CLI (sscli),它基于 .NET 2.0 框架,并且部分不完整。它包含该函数 ( clr\src\vm\hosting.cpp
) 的定义,但它只是一个存根。最后它会使用一些手段来重启进程(例如Win32的CreateProcess
API)。
否则:该应用程序是“常规”.NET 应用程序。Environment.GetCommandLineArgs()
用于重新创建原始命令行并Process.Start(Application.ExecutablePath)
用于重新启动应用程序。
使用Application.Exit
-mechanism 来尝试结束当前实例可能是您发现它不可靠的原因。取消发送关闭事件的表单可以中断它。另请参阅此SO 问题。