如何在Windows注销确定之前保持用户进程运行?

如何在Windows注销确定之前保持用户进程运行?,windows,winapi,Windows,Winapi,我有一个在Windows上运行的应用程序,在用户会话中,我不希望用户能够意外关闭它 用户可以关闭它的一种方法是拥有未保存的数据(例如,在记事本中)并启动注销过程。记事本拒绝WM_查询会话消息;Windows提示用户存在未保存的数据;用户可以取消注销 其他应用程序(包括我的),获取WM_QUERYSESSION,用TRUE响应,然后获取WM_ENDSESSION,然后退出。重要的是,他们在Windows决定提示用户记事本中未保存的数据之前就退出了 如果用户取消注销,最终结果是用户的会话将继续,而没

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

用户可以关闭它的一种方法是拥有未保存的数据(例如,在记事本中)并启动注销过程。记事本拒绝WM_查询会话消息;Windows提示用户存在未保存的数据;用户可以取消注销

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

如果用户取消注销,最终结果是用户的会话将继续,而没有所有处理结束会话消息的进程

我试图找到一种方法,让我的进程一直运行,直到我们超过了用户可以取消注销的点。看看微软的文档,我看不出一个明显的方法来做到这一点——每个进程都有自己的WM_QUERYSESSION>WM_ENDSESSION,文档中明确指出,每个应用程序都会独立地发生这种情况

我不想用FALSE回复WM_QUERYSESSION,因为我自己也不想阻止注销,只要在其他东西阻止它时保持运行即可

是否有其他方法可以确定Windows何时决定所有WM_QUERYSESSION消息都以TRUE回复,并且注销是不可避免的


(我认为这是一个Windows问题,而不是我使用的语言特有的问题,但如果有问题,它是PureBasic。不过,任何Win32 API方法都应该是可行的。)

如果任何应用程序在
WM\u QUERYENDSESSION
中返回FALSE,已返回TRUE的应用程序将收到带有
wParam=FALSE的
WM_ENDSESSION
,以指示关机已取消

如果所有应用程序都返回TRUE至
WM_QUERYENDSESSION
,则它们才会收到
WM_ENDSESSION
,其中
wParam=TRUE
,以指示关机正在进行

有关
WM_QUERYENDSESSION
WM_ENDSESSION
工作方式的更多详细信息,请参阅和

您的应用程序是否注意到
WM_ENDSESSION
给出的
wParam
值?或者它只是在接收到
WM_ENDSESSION
时盲目地无条件退出?并不是所有的应用程序都像应该的那样关注用户。确保你的是


更新:根据文档和文档:

当应用程序为
WM\u QUERYENDSESSION
返回TRUE时,它将接收
WM\u ENDSESSION
消息并终止,无论其他应用程序如何响应
WM\u QUERYENDSESSION
消息。

所以,你的应用程序在这里真的无能为力。一旦它响应
TRUE
WM\u QUERYENDSESSION
,游戏就结束了。您的应用程序将收到
WM_ENDSESSION
,如果在几秒钟内没有退出,则会被强制终止,而不管其他应用程序如何响应关闭


因此,我能想到的真正检测会话何时实际结束的唯一方法是使用服务,因为服务可以接收
service\u CONTROL\u SHUTDOWN
service\u CONTROL\u SESSIONCHANGE
通知。

是的,我正在注意这一点。问题是我立即收到一个带有wParam TRUE的WM_ENDSESSION,也就是说,在用户看到允许他们取消注销的提示之前几秒钟(不管他们单击“取消”按钮的时间有多长),该服务也没有记录,但用户会话中没有运行该服务,并且无法向用户显示窗口,或重新启动用户块。就这些信息而言,我得出了与上面相同的结论——游戏到此结束了——但我想我在这里提出这个问题有两个原因。1.并非所有windows进程都会退出(例如资源管理器本身不会退出),因此在注销过程中必须有一些(未记录的?)方法留在周围,以及2;鉴于这种行为,WM_ENDSESSION上的wParam用于什么?计时是这样的,您永远不会在wParam为FALSE的情况下收到它。“我也有一个服务-但它没有在用户会话中运行”-不,但它可以检测用户会话何时运行,然后相应地采取行动。“并且不能向用户显示窗口”-实际上,它可以使用
WTSSendMessage()
查看简单的弹出消息,或者
CreateProcessAsUser()
在用户会话中启动UI应用程序。“或重新启动用户部件”-再次,
CreateProcessAsUser()
。“并非所有windows进程都会退出(例如,资源管理器本身不会退出)”-资源管理器是默认的用户shell,因此在会话结束之前不会终止。在这种情况下,CreateProcessAsUser()看起来是正确的答案-我不知道您可以在不知道用户密码的情况下执行此类操作。谢谢你的帮助!