如何确保用户进程在Windows注销明确之前一直运行?

时间:2018-09-10 14:40:21

标签: windows winapi

在用户会话中,我有一个正在Windows上运行的应用程序,我不希望用户能够意外关闭。

用户可以关闭数据的一种方法是保存未保存的数据(例如在记事本中)并开始注销过程。记事本拒绝WM_QUERYSESSION消息; Windows提示用户未保存的数据;并且用户可以取消注销。

其他应用程序(包括我的应用程序),获取WM_QUERYSESSION,以TRUE响应,然后获取WM_ENDSESSION,然后退出。重要的是,他们在Windows甚至决定提示用户有关记事本中未保存的数据之前就退出了。

如果用户取消注销,则最终结果是该用户的会话继续进行,而没有遵循该结束会话消息的所有过程。

我试图找到一种解决方法,就是保持进程运行,直到我们超过了用户可以取消注销的程度为止。查看有关此内容的Microsoft文档,我没有发现一种明显的方式-每个进程都通过其自己的WM_QUERYSESSION> WM_ENDSESSION,并且该文档明确指出,这对于每个应用程序都是独立发生的。

我不想用FALSE回复WM_QUERYSESSION,因为我不想自己阻止注销,只要有其他阻止,请保持运行。

是否还有其他方法可以确定Windows是否已确定所有WM_QUERYSESSION消息均以TRUE答复,并且注销不可避免?

(我认为这是Windows问题,而不是我正在使用的语言的特定问题,但万一重要,那就是PureBasic。不过,任何Win32 API方法都应该可行。)

1 个答案:

答案 0 :(得分:2)

如果任何应用返回FALSE到WM_QUERYENDSESSION,则已经返回TRUE的应用将收到带有WM_ENDSESSION的{​​{1}},表示关闭已被取消。

如果所有应用都将TRUE返回到wParam=FALSE,则只有它们会收到WM_QUERYENDSESSIONWM_ENDSESSION的{​​{1}},表明关闭正在进行。

有关wParam=TRUEWM_QUERYENDSESSION的工作方式的更多详细信息,请参见Application Shutdown Changes in Windows VistaRestart Manager: Guidelines for Applications

您的应用是否关注WM_ENDSESSION给出的wParam值?还是在收到WM_ENDSESSION时无条件退出?并非所有应用程序都应引起注意。确保是你的。


更新:根据WM_QUERYENDSESSION文档和Logging Off文档:

  

当一个应用程序对WM_ENDSESSION返回TRUE时,它会收到WM_QUERYENDSESSION消息并终止,无论其他应用程序如何响应WM_ENDSESSION消息,。 strong>

因此,您的应用程序在这里实际上无能为力。一旦WM_QUERYENDSESSIONTRUE作出响应,就结束了。无论其他应用如何响应关闭,您的应用都会在几秒钟内没有退出的情况下收到WM_QUERYENDSESSION并被强制终止。

因此,我想真正检测到会话实际结束时间的唯一方法是改用服务,因为服务可以接收WM_ENDSESSIONSERVICE_CONTROL_SHUTDOWN通知。