如何检测Windows关机或在Qt中注销

问题描述:

我正在将一个Linux应用程序移植到Qt中编写的Windows中。应用程序需要在关闭之前保存一些设置。在Linux上,我们可以通过SIGTERM的信号处理程序来做到这一点。我如何在Windows上实现相同的功能。如何检测Windows关机或在Qt中注销

如果使用了Qt事件循环,可以赶上以下信号:

空隙QCoreApplication :: aboutToQuit()[信号]

当应用程序即将这个信号被发射退出主事件循环,例如当事件循环等级下降到零时。在从应用程序内部调用quit()或用户关闭整个桌面会话之后,可能会发生这种情况。 如果您的应用程序必须执行一些最后一次清理,该信号特别有用。请注意,在这种状态下不能进行用户交互。

除此之外,你可能会寻找以下消息下方,如果上述信号是不适合你的使用情况:

WM_QUIT:http://msdn.microsoft.com/en-us/library/windows/desktop/ms632641(v=vs.85).aspx

WM_CLOSE:http://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs.85).aspx

WM_QUERYENDSESSION :http://msdn.microsoft.com/en-US/library/windows/desktop/aa376890.aspx

WM_ENDSESSION:http://msdn.microsoft.com/en-US/library/windows/desktop/aa376889.aspx

我不知道Qt。如果你能买得起Windows,只有WM_QUERYENDSESSIONWM_ENDSESSION消息可能是正确的做法。

我认为其他答案完全错过了点:当你强行结束一个应用程序,就像在Unix上的SIGKILL。 没有办法处理它 - 除了提前我的意思是提前处理它,确保每次更改设置时都保存设置。当然,您可以优化此行为,例如,如果您希望最大限度地减少磁盘访问次数(考虑移动设备上的功耗),如果它们很脏,则每隔几秒保存设置一次。

很多这是由QSettings为您处理。只要你使用QSettings,你会得到合理的行为。如果你自己保存文件,使用QSaveFile,因为它处理文件的刷新和接近原子文件的替换,所以如果kill(强制终止)出现在写作的中间,你将不会丢失设置。

QCoreApplication发出的aboutToQuit信号是你想要做出的反应,如果你想简单地做一些事情,当应用程序被要求退出。这相当于在Unix上处理WM_QUIT消息,或处理SIGTERM。因此,以特定于平台的方式来做这件事是没有意义的,因为Qt已经为你做了。处理WM_CLOSE同样没有意义,因为这是一个只有Windows获得的消息,并且Qt已经为您处理。

您还可以通过安装QAbstractNativeEventFilter并处理WM_ENDSESSIONWM_QUERYENDSESSION来参与注销/关闭过程。如果您想提前知道该应用程序将被退出,这只是有意义的。除非您明确要停止关机/注销,否则您不必担心。

+0

我不知道abouttoQuit处理在Linux上SIGTERM,但对于SIGHUP和SIGINT,SIGHUP通常发送到在Linux的应用程序注销,这就是为什么我使用的信号处理程序(特定于Qt方式平台)在Linux上 –

+0

这个问题没有任何说的是应用程序被强制结束。它提到'SIGTERM'这是一个优雅的关机信号,而不是'SIGKILL'。 – qris

我认为最好是处理QApplication::commitDataRequest信号(或Qt5中的QGuiApplication::commitDataRequest)而不是aboutToQuit。只需将信号连接到您的功能以保存设置。

这里有一些相关的讨论:http://qt-project.org/forums/viewthread/33329