Windows 7下阻止系统关机

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

  下面这段代码就是完整实现,不能使用VS2005编译,因为自带的库还没有这俩函数,我是使用VS2010编译的,工程文件和可执行文件的下载地址在文章最下方。

  1 #include <windows.h>
  2 #include <tchar.h>
  3 #include "resource.h"
  4
  5 //标记是否已经阻止关机,默认为未阻止
  6 BOOL blockedFlag = FALSE;
  7
  8 //这俩函数纯粹是撒娇,为了突出它们才拿出来改个名的
  9 BOOL BlockShutdown(HWND hwnd)
 10 {
 11     if (ShutdownBlockReasonCreate(hwnd, _T("不准关机!除非你点强制关机 :-(")))
 12     {
 13         return TRUE;
 14     }
 15     return FALSE;
 16 }
 17
 18 BOOL UnblockShutdown(HWND hwnd)
 19 {
 20     if (ShutdownBlockReasonDestroy(hwnd))
 21     {
 22         return TRUE;
 23     }
 24     return FALSE;
 25 }
 26
 27 INT_PTR CALLBACK MainDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 28 {
 29     switch(uMsg)
 30     {
 31     case WM_INITDIALOG:
 32         SetDlgItemText(hwndDlg, IDC_STATIC_STATUS, _T("未阻止关机"));
 33         return TRUE;
 34     case WM_CLOSE:
 35         if (blockedFlag)
 36         {
 37             if (UnblockShutdown(hwndDlg))
 38             {
 39                 EndDialog(hwndDlg, 0);
 40                 return TRUE;
 41             }
 42             if (IDYES == MessageBox(hwndDlg, _T("解除阻止失败……还要继续关闭程序么(关闭程序后不影响关机)?"), _T("提示"), MB_YESNO))
 43             {
 44                 EndDialog(hwndDlg, 0);
 45                 return TRUE;
 46             }
 47             return FALSE;
 48         }
 49         EndDialog(hwndDlg, 0);
 50         return TRUE;
 51     case WM_QUERYENDSESSION:
 52         if (blockedFlag)        //不要以为只调用BlockShutdownReasonCreate就行了,WM_QUERYENDSESSION也得拦住
 53         {
 54             return TRUE;
 55         }
 56         return FALSE;
 57     case WM_COMMAND:
 58         switch(LOWORD(wParam))
 59         {
 60         case IDC_BUTTON_BLOCK:
 61             if (blockedFlag)
 62             {
 63                 MessageBox(hwndDlg, _T("已经阻止关机,请点击关机测试。"), _T("提示"), MB_OK);
 64             }
 65             else
 66             {
 67                 if (BlockShutdown(hwndDlg))
 68                 {
 69                     SetDlgItemText(hwndDlg, IDC_STATIC_STATUS, _T("已经阻止关机"));
 70                     blockedFlag = TRUE;
 71                 }
 72                 else
 73                 {
 74                     MessageBox(hwndDlg, _T("阻止关机失败了……"), _T("提示"), MB_OK);
 75                 }
 76             }
 77             return TRUE;
 78         case IDC_BUTTON_UNBLOCK:
 79             if (!blockedFlag)
 80             {
 81                 MessageBox(hwndDlg, _T("未阻止关机,无需解除。"), _T("提示"), MB_OK);
 82             }
 83             else
 84             {
 85                 if (UnblockShutdown(hwndDlg))
 86                 {
 87                     SetDlgItemText(hwndDlg, IDC_STATIC_STATUS, _T("未阻止关机"));
 88                     blockedFlag = FALSE;
 89                 }
 90                 else
 91                 {
 92                     MessageBox(hwndDlg, _T("解除阻止失败了……"), _T("提示"), MB_OK);
 93                 }
 94             }
 95             return TRUE;
 96         default:
 97             return FALSE;
 98         }
 99     default:
100         return FALSE;
101     }
102     return FALSE;
103 }
104 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
105 {
106     DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, MainDialogProc);
107     return 0;
108 }

  下图就是运行效果。

  上面这个图应该很多人看到过,只是通常刚一显示就消失了,这样就不会消失了,直到程序调用了ShutdownBlockReasonDestroy。

  还有一点需要注意的是,如果你的电脑安装了360安全卫士orQQ电脑管家等优化软件,通常都会一键优化给优化掉……你就看不到这个对话框了,程序直接被枪毙掉了,因为这样可以加快关机速度 :-(

  完整的C语言工程和可执行程序文件都在压缩包里,为了方便没装VS2010的童鞋测试程序效果,msvcr100.dll我也放到release目录下了,下载地址是http://files.cnblogs.com/pianoid/ShutdownBlocker.rar

Windows 7下阻止系统关机,码迷,mamicode.com

时间: 2024-10-13 06:20:48

Windows 7下阻止系统关机的相关文章

VC++下实现系统关机、重启

关机调用: 文章来源:http://dqifa.blog.163.com/blog/#m=0&t=1&c=fks_095066086083081065092081074071093084084075087080083MyExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_POWEROFF); 重启调用: MyExitWindowsEx(EWX_REBOOT | EWX_FORCE); 具体实现: BOOL IsWIN32_NT() {  OSVERSI

ubuntu18.04 &amp; Windows10 双系统关机缓慢

1.Windows与Ubuntu双系统关机缓慢并不少见,有时单系统下的Linux mint或Ubuntu都会出现这个现象.主要原因是还有没有关闭的进程或者是软件兼容的原因,所以导致每次关机都有一个90秒的等待时间,所以用户觉得关机缓慢. 2.解决方法: a.打开terminal输入sudo apt-get install watchdog b.配置watchdog,输入sudo enable watchdog.service c.开启watchdog,输入sudo start watchdog.

C#实现控制Windows系统关机、重启和注销的方法:

shutdown命令的参数: shutdown.exe -s:关机shutdown.exe -r:关机并重启shutdown.exe -l:注销当前用户 shutdown.exe -s -t 时间:设置关机倒计时shutdown.exe -h:休眠shutdown.exe -t 时间:设置关机倒计时.默认值是 30 秒.shutdown.exe -a:取消关机shutdown.exe -f:强行关闭应用程序而没有警告shutdown.exe -m \计算机名:控制远程计算机shutdown.ex

C#捕获windows关机事件,在系统关机前做一些自己想做的事

C#捕获windows关机事件,在系统关机前做一些自己想做的事: 有些时候我们可能想在Windows关机时记录或处理一些事情,这里提供几种方法. 方法一: /// <summary> /// 窗口过程的回调函数 /// </summary> /// <param name="m"></param> protected override void WndProc(ref Message m) { switch (m.Msg) { //此消息

C#实现控制Windows系统关机、重启和注销的方法

shutdown.exe -s:关机shutdown.exe -r:关机并重启shutdown.exe -l:注销当前用户 shutdown.exe -s -t 时间:设置关机倒计时shutdown.exe -h:休眠shutdown.exe -t 时间:设置关机倒计时.默认值是 30 秒.shutdown.exe -a:取消关机shutdown.exe -f:强行关闭应用程序而没有警告shutdown.exe -m \计算机名:控制远程计算机shutdown.exe -i:显示"远程关机&qu

Windows 系统关机、重启、睡眠、休眠及唤醒消息

今天要查找如何获取系统从睡眠.休眠状态下唤醒的消息,写了个MFC对话框的程序,贴出部分核心代码: //唤醒消息捕获 LRESULT CSystemResumedMessageDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: 在此添加专用代码和/或调用基类 if ((message == WM_POWERBROADCAST) && (wParam == PBT_APMRESUMEAUTOMATIC))

Windows 7下硬盘安装Ubuntu 14.04图文教程 第3页_Linux教程_Linux公社-Linux系统门户网站 - 猎豹安全浏览器

Windows 7下硬盘安装Ubuntu 14.04图文教程 部分安装图: 下面的安装选择默认吧,不要改动什么(对菜菜鸟来说). 点击 现在重启 即可. 如果没有按本教程做的,看看下面的一些情况,可能对你有帮助. 注意: (1)在选择安装启动引导器的设备时,可以选择我们分好的 / 区,也可以新建一个/boot区. (2)若重启就会发现原来 Windows进不去了. 打开终端输入命令 sudo gedit /etc/default/grub 修改GRUB_TIMEOUT="10"然后在终

如何在Windows Server 2008 R2没有磁盘清理工具的情况下使用系统提供的磁盘清理工具

今天,刚好碰到服务器C盘空间满的情况,首先处理了临时文件和有关的日志文件后空间还是不够用,我知道清理C盘的方法有很多,但今天只分享一下如何在Windows Server 2008 R2没有磁盘清理工具的情况下使用系统提供的磁盘清理工具. 一.在Windows Server 2008 R2,右击C盘,选择属性,弹出下面的界面: 即没有下面清理C盘的工具: 那如何使用系统自带的清理工具呢. 二.驱动器的常规属性和 cleanmgr.exe 磁盘清理选项不是默认情况下出现在 Windows Serve

Windows 7/8/10 系统下Laravel框架的开发环境安装及部署详解(Vagrant + Homestead)

注意! laravel/homestead box项目地址已经不再是原来的 https://atlas.hashicorp.com/laravel/boxes/homestead 而已经变更成 https://app.vagrantup.com/laravel/boxes/homestead 如果是刚刚接触Laravel的朋友,请直接按文中步骤操作.需要更新及重装的朋友们请注意使用第二个地址来进行文中操作. 虽然我通常习惯在Linux环境下工作,但对于一个从小就接触Windows的人来说,能够在