当按下电源键时,如果有应用程序阻止关机。根据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.先显示关机界面,再显示正在关闭打开的应用程序,是否仍要关机界面)。
我也遇到了相同的问题,是win10系统下的
可以捕获关机事件, WM_QUERYENDSESSION 消息,或 它发出的 WM_ENDSESSION 消息 便可。
例如 win API 程序中:
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
...
switch(message)
{
case WM_QUERYENDSESSION : 这里获得了关机事件; break;
case WM_ENDSESSION: 这里获得了; break;
....
}
}
如有帮助,请采纳,十分感谢!
先给出答案:修改注册表:“ HKEY_USERS\用户sid\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects{51ADFA1F-DEF1-42BB-A4E7-C5B05059BC14}Machine\SOFTWARE\Policies\Microsoft\Windows\System\AllowBlockingAppsAtShutdown”的值为1。应该就可以了。修改注册表的api,大佬会hook的人应该不用我说了。
这边给出我的方案来源:
修改本地组策略的:计算机配置 \管理模板\系统\关机选项的“关闭会阻止或取消关机的应用程序的自动关闭终止功能”。如果启用此设置,则没有可见顶级窗口且阻止或取消关机的控制台应用程序或 GUI 应用程序不会在关机期间自动终止。如图1。经验证可行。但题主需要在程序中实现,所以应该找出对应的注册表项。
我查了一下组策略其实对应着注册表的某一项值,利用火绒剑可以追去 本地组策略编辑器修改的具体注册表值。如图2。
图1:
图2:
你目前实现的比较复杂,又是系统策略又是hook的,我觉得最好的方式是挂钩子,做一个全局钩子挂上,这样在WM_QUERYENDSESSION 消息中终止系统的操作,换成弹出你的控制框即可。不是你的那种硬hook掉ExitWindowsEx。有帮助请采纳谢谢!
1,在“运行”框输入“gpedit.msc”,回车。
2,本地组策略编辑器中,依次展开:“计算机配置”→“管理模板”→“系统”→“关机选项”。
3,双击“关闭会阻止或取消关机的应用程序的自动终止功能”
4,选择“已启用”,问题解决
按Win+R打开运行,输入gpedit.msc回车打开组策略编辑器
依次展开计算机配置→管理模板→系统,双击打开右侧关机
双击打开“关闭会阻止或取消关机的应用程序的自动终止功能”
选择“已启用”,点击确定,这个时候在关机就不需要手动点击关闭了,但是会有结束进程的倒计时提示,一旦后台程序多,反而更费时
直接在启动弹窗的代码前用break语句不就好了吗。(这个回答的作者是个学Python的小学生)
修改注册表