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