Windows 7下阻止系统关机
从Vista开始,想阻止系统关机就开始变麻烦了,不能只拦截WM_QUERYENDSESSION了,操作系统只给一个应用程序两秒钟的时间去保存自己的东西,两秒钟之后,不管做完了没有,Game Over!可是如果你正在刻录一张光盘呢?两秒钟是都不够的,所以Vista之后也给提供了一种方式阻止系统关机,就是ShutdownBlockReasonCreate函数,只要调用这个函数,第一个参数传递创建主窗口的句柄,第二个参数传递一个字符串,这个字符串说明阻止关机的原因,将会显示给用户。而且msdn提示说这个API函数只能由创建主窗口的线程调用,否则将返回ERROR_ACCESS_DENIED。而且完成后还得调用ShutdownBlockReasonDestroy函数使系统关机能够继续进行,参数只传递上面那个窗口的句柄就可以了。
下面这段代码就是完整实现,不能使用VS2005编译,因为自带的库还没有这俩函数,我是使用VS2010编译的,工程文件和可执行文件的下载地址在文章最下方。

#include <windows.h>
#include <tchar.h>
#include "resource.h"
//标记是否已经阻止关机,默认为未阻止
BOOL blockedFlag = FALSE;
//这俩函数纯粹是撒娇,为了突出它们才拿出来改个名的
BOOL BlockShutdown(HWND hwnd)
{
if (ShutdownBlockReasonCreate(hwnd, _T("不准关机!除非你点强制关机 :-(")))
{
return TRUE;
}
return FALSE;
}
BOOL UnblockShutdown(HWND hwnd)
{
if (ShutdownBlockReasonDestroy(hwnd))
{
return TRUE;
}
return FALSE;
}
INT_PTR CALLBACK MainDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
SetDlgItemText(hwndDlg, IDC_STATIC_STATUS, _T("未阻止关机"));
return TRUE;
case WM_CLOSE:
if (blockedFlag)
{
if (UnblockShutdown(hwndDlg))
{
EndDialog(hwndDlg, );
return TRUE;
}
if (IDYES == MessageBox(hwndDlg, _T("解除阻止失败……还要继续关闭程序么(关闭程序后不影响关机)?"), _T("提示"), MB_YESNO))
{
EndDialog(hwndDlg, );
return TRUE;
}
return FALSE;
}
EndDialog(hwndDlg, );
return TRUE;
case WM_QUERYENDSESSION:
if (blockedFlag) //不要以为只调用BlockShutdownReasonCreate就行了,WM_QUERYENDSESSION也得拦住
{
return TRUE;
}
return FALSE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BUTTON_BLOCK:
if (blockedFlag)
{
MessageBox(hwndDlg, _T("已经阻止关机,请点击关机测试。"), _T("提示"), MB_OK);
}
else
{
if (BlockShutdown(hwndDlg))
{
SetDlgItemText(hwndDlg, IDC_STATIC_STATUS, _T("已经阻止关机"));
blockedFlag = TRUE;
}
else
{
MessageBox(hwndDlg, _T("阻止关机失败了……"), _T("提示"), MB_OK);
}
}
return TRUE;
case IDC_BUTTON_UNBLOCK:
if (!blockedFlag)
{
MessageBox(hwndDlg, _T("未阻止关机,无需解除。"), _T("提示"), MB_OK);
}
else
{
if (UnblockShutdown(hwndDlg))
{
SetDlgItemText(hwndDlg, IDC_STATIC_STATUS, _T("未阻止关机"));
blockedFlag = FALSE;
}
else
{
MessageBox(hwndDlg, _T("解除阻止失败了……"), _T("提示"), MB_OK);
}
}
return TRUE;
default:
return FALSE;
}
default:
return FALSE;
}
return FALSE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, MainDialogProc);
;
}

下图就是运行效果。

上面这个图应该很多人看到过,只是通常刚一显示就消失了,这样就不会消失了,直到程序调用了ShutdownBlockReasonDestroy。
还有一点需要注意的是,如果你的电脑安装了360安全卫士orQQ电脑管家等优化软件,通常都会一键优化给优化掉……你就看不到这个对话框了,程序直接被枪毙掉了,因为这样可以加快关机速度 :-(
完整的C语言工程和可执行程序文件都在压缩包里,为了方便没装VS2010的童鞋测试程序效果,msvcr100.dll我也放到release目录下了,下载地址是http://files.cnblogs.com/pianoid/ShutdownBlocker.rar。
Windows 7下阻止系统关机的更多相关文章
- Windows/Linux下查看系统CPU使用最高的线程
参考:https://blog.csdn.net/qq_27818157/article/details/78688580 jstack -l 31372 > c:/31372.stack
- ubuntu18.04 & Windows10 双系统关机缓慢
1.Windows与Ubuntu双系统关机缓慢并不少见,有时单系统下的Linux mint或Ubuntu都会出现这个现象.主要原因是还有没有关闭的进程或者是软件兼容的原因,所以导致每次关机都有一个90 ...
- C#实现控制Windows系统关机、重启和注销的方法:
shutdown命令的参数: shutdown.exe -s:关机shutdown.exe -r:关机并重启shutdown.exe -l:注销当前用户 shutdown.exe -s -t 时间:设 ...
- C#实现控制Windows系统关机、重启和注销的方法
shutdown命令的参数: shutdown.exe -s:关机shutdown.exe -r:关机并重启shutdown.exe -l:注销当前用户 shutdown.exe -s -t 时间:设 ...
- 如何在Windows Server 2008 R2没有磁盘清理工具的情况下使用系统提供的磁盘清理工具
今天,刚好碰到服务器C盘空间满的情况,首先处理了临时文件和有关的日志文件后空间还是不够用,我知道清理C盘的方法有很多,但今天只分享一下如何在Windows Server 2008 R2没有磁盘清理工具 ...
- Windows 7/8/10 系统下Laravel框架的开发环境安装及部署详解(Vagrant + Homestead)
注意! laravel/homestead box项目地址已经不再是原来的 https://atlas.hashicorp.com/laravel/boxes/homestead 而已经变更成 htt ...
- Windows和Linux双系统下完美卸载linux
装了Windows和linux双系统的朋友,在后期要删除linux是个比较头痛的问题,因为MBR已经被linux接管,本文的目的是如何在windows 和linux双系统下,简单,完美地卸载linux ...
- 如何在Windows环境下安装Linux系统虚拟机
如何在Windows环境下安装Linux系统虚拟机 本篇经验写给想要入门学习C语言的小白们.Windows系统因为使用窗口图形化,操作简单,功能多样,所以我们在Windows环境下可以做到很多,但想要 ...
- 使用PHPstudy在Windows服务器下部署PHP系统
PHP网站一般运行在Apache服务器上,IIS服务器上也可以运行,但是不推荐,windows服务器上没有集成Apache跟PHP的运行环境,但是借助第三方的软件就能很好的搞定,一般这样的软件有很多, ...
随机推荐
- Chrome中xpath表达式巧妙获取
对于xpath语法不熟悉,或者要快速匹配出xpath的小伙伴来说这种方式是最快捷的了. 步骤如下: 1.打开chrome 2.ctrl + shift + c 个人比较喜欢用快捷键,不喜欢用快捷键的就 ...
- 100、RESTful API
本篇导航: RESTful RESTful API设计 基于django实现 基于Django Rest Framework框架实现 一.RESTful REST与技术无关,代表的是一种软件架构风格, ...
- iOS-PYSearch 完美搜索页
APP搜索页基本上是少不了的,热门搜索.搜索记录等:这里推荐一个大牛ko1o写的:PYSearch,他还有一个不错的图片浏览开源:PYPhotoBrowser:这个也不错,感兴趣的可以了解下:下面说下 ...
- IDEA tomcat启动异常 org.apache.catalina.startup.ContextConfig parseWebXml
启动Tomcat发现有异常,总是无法启动,具体的异常日志为下图 具体的解决方法为:在tomcat的conf/content.xml中加上<Loader delegate="true&q ...
- BZOJ 1202: [HNOI2005]狡猾的商人 [带权并查集]
题意: 给出m个区间和,询问是否有区间和和之前给出的矛盾 NOIp之前做过hdu3038..... 带权并查集维护到根的权值和,向左合并 #include <iostream> #incl ...
- 夏令营提高班上午上机测试 Day 2 解题报告
那一天,日照一中夏令营数据结构提高班的同学们终于想起了,被Day2上午的三道题支配的恐惧…… 是的..这一天的题有点难想.. 本来打算前天写这篇随笔,然而前天在机房和同学打luogu月赛…… 昨天 ...
- POJ1741Tree [点分治]【学习笔记】
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 20098 Accepted: 6608 Description ...
- ASP.NET Core 入门
关于ASP.NET Core ASP.NET Core 是一个全新的开源.跨平台框架,可以用它来构建基于网络连接的现代云应用程序,比如:Web 应用,IoT(Internet Of Things,物联 ...
- AJAX面试题都在这里
AJAX常见面试题 什么是AJAX,为什么要使用Ajax AJAX是"Asynchronous JavaScript and XML"的缩写.他是指一种创建交互式网页应用的网页开发 ...
- R语言-选择样本数量
功效分析:可以帮助在给定置信度的情况下,判断检测到给定效应值时所需的样本量,也可以在给定置信水平的情况下,计算某样本量内可以检测到的给定效应值的概率 1.t检验 案例:使用手机和司机反应时间的实验 l ...