重新启动PC后,C#.Net exe不会关闭,从而使计算机无法重新启动

时间:2020-03-06 15:05:26  来源:igfitidea点击:

我们有一个内置于C中的SmartClient,当重新启动运行于其上的PC时,它将保持打开状态。除非用户先关闭SmartClient或者进行其他手动干预,否则这将终止重新启动过程。

当基础结构团队远程安装需要重新启动计算机的新软件时,这会引起问题。

关于让SmartClient应用识别Windows的关闭/重新启动事件并优雅地杀死自己的任何想法?

更新:
这是一个具有多个gui线程的高线程应用程序。是的,多个gui线程。它实际上是对许多项目的合并,这些项目本身可以是独立的应用程序,所有这些都可以从单个exe启动和管理,该exe集中了这些管理方法并跟踪那些线程。我不认为使用后台线程是一种选择。

解决方案

通常,.Net应用程序至少会正确响应,这是"开箱即用"的行为。如果不是这样,可能会发生许多事情。最好的猜测是,我们对程序的了解不多,是我们在主UI线程中运行了一个长时间运行的进程,这阻止了该应用程序响应窗口消息。

还是.Net应用程序故意忽略关闭或者退出消息?

它必须是一个继续运行的线程,以防止应用程序关闭。如果我们使用线程,一个简单的解决方法是将其设置为后台。

A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete.
  
  http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx

好的,如果我们有权访问该应用程序,则可以处理SessionEnded事件。

...
Microsoft.Win32.SystemEvents.SessionEnded +=new
  Microsoft.Win32.SessionEndedEventHandler(shutdownHandler);

...

private void shutdownHandler(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
  // Do stuff
}

后台线程是一种快速而肮脏的解决方案,最好的解决方案是使用同步对象(" ManualResetEvent"," Mutex"或者其他对象)来停止其他线程。

否则,请跟踪所有打开的窗口,并在主应用程序关闭时发送" WM_CLOSE"消息。

我们必须提供有关如何启动这些GUI应用程序的更多信息。也许我们为每个应用程序启动一个线程并调用Application.Run(new Form1());

我们也可以考虑为每个GUI应用程序创建一个" AppDomain"

当用户注销或者关闭Windows时," WM_QUERYENDSESSION"消息将发送到所有顶级窗口。请参阅此处的MSDN文档。

WinForm应用程序响应此消息的默认行为是使用CloseReason == WindowsShutDown或者其他事件触发FormClosing事件。事件处理程序可以选择固执并拒绝关闭应用程序,从而保持系统运行。

检查应用程序的" FormClosing"处理程序。也许那里有东西。我已经看过几次这样的东西。