此问题与如何重新启动应用程序无关.我已经通过使用Mutex和辅助启动器应用程序实现了这一目标.在使用Application.Restart遇到一些问题后,我不得不求助于此.
无论如何,我不熟悉IL,我想知道是否有人可以解释Application.Restart的工作原理.它是对运行时的调用,但运行时究竟做了什么?它如何关闭现有实例以及它如何知道何时启动新实例?
......不熟悉IL,......
您是否考虑过使用反编译器(Reflector,dotPeek),或者更好的是使用.NET框架的参考源代码?
无论如何.
随便看看它做了以下事情:
在以下所有情况下,使用终止当前实例Application.ExitInternal()
.这是公共Application.Exit()
方法的要点,省略了一些安全检查/断言.
看看它是否可以确定Assembly.GetEntryAssembly()
.如果这是null
调用,Application.Restart()
很可能是从非托管代码完成的,并且操作会NotSupportedException
向调用者抛出一个.
查看当前进程是否是ieexec.exe
,如果是,请使用它来重新启动应用程序(有关详细信息,ieexec.exe
请参阅此处).实际上这几乎也是一个Process.Start()
调用ieexec.exe
,但命令行参数不是通过Environment.GetCommandLineArgs()
(见下文)收集,而是通过读取APP_LAUNCH_URL
应用程序域数据.
查看应用程序是否为click-once应用程序(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来尝试结束当前实例可能是你发现它不可靠的原因.取消发送结束事件的表单可以中断它.另见这个问题.