6

这个问题不是关于如何重新启动应用程序。我已经通过使用 Mutex 和辅助启动器应用程序实现了这一目标。在使用 Application.Restart 遇到一些问题后,我不得不求助于它。

无论如何,我不熟悉 IL,我想知道是否有人可以首先解释 Application.Restart 是如何工作的。这是对运行时的调用,但运行时到底做了什么?它如何关闭现有实例以及如何知道何时启动新实例?

4

1 回答 1

8

... 不流利使用 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的CreateProcessAPI)。

  • 否则:该应用程序是“常规”.NET 应用程序。Environment.GetCommandLineArgs()用于重新创建原始命令行并Process.Start(Application.ExecutablePath)用于重新启动应用程序。

使用Application.Exit-mechanism 来尝试结束当前实例可能是您发现它不可靠的原因。取消发送关闭事件的表单可以中断它。另请参阅SO 问题。

于 2013-06-19T04:44:26.933 回答