问题遇到的现象和发生背景
当按下电源键时,如果有应用程序阻止关机。根据gpedit.msc中的关机选项设置,有两种不同的表现,一种是出现结束程序弹窗,一种是出现关机界面然后出现正在关闭打开的应用程序界面。
问题复现
如果需要复现该问题,可以将关机选项设置为已启用,重启后,在VS新建一个win32项目在WndProc函数中添加
case WM_QUERYENDSESSION:
return 0;//此处返回0则不能关机,返回1就能关机。
然后运行程序,按下电源关机键就能看到结束程序弹窗了。
设置为禁用,按下电源关机键会出现关机界面然后出现正在关闭打开的应用程序,是否仍要关机界面。
问题相关代码,请勿粘贴截图
目前我的应用程序所做的处理是监听WM_QUERYENDSESSION消息,然后显示确认/取消弹窗,同时用一个线程来关闭出现的结束程序窗口,但是会出现这个窗口一闪而过。
我的解答思路和尝试过的方法
1.我只尝试过将关机选项设置为已启用,这样就会出现结束程序弹窗,然后我找到这个结束程序弹窗是由csrss.exe进程生成的,我尝试去hook这个进程替换其ExitWindowsEx函数行为,但是会出现蓝屏,应该是由于这个进程是系统进程。hook我自己写的应用进程中的ExitWindowsEx函数是可以实现的。以及通过全局钩子去hook这个进程,但是这个进程并不会触发钩子的回调函数,就像没有消息循环一样。
2.我尝试了通过修改电源选项中的按下关机按键表现行为进行尝试,但是当设置为睡眠、休眠、关闭显示器都会导致屏幕熄灭。设置为无任何操作,我的应用程序又接收不到任何消息,无法确定电源键按下这一行为。
我想要达到的结果
按下电源关机键后,由我的应用程序弹窗来提示用户是否关机,根据我的程序来控制关机(这一步已实现),并且不出现上面两种行为(这是问题所在,1.出现弹窗,2.先显示关机界面,再显示正在关闭打开的应用程序,是否仍要关机界面)。