zoukankan      html  css  js  c++  java
  • Windows 7下阻止系统关机 分类: windows驱动程序WDM 2014-04-29 14:43 562人阅读 评论(1) 收藏

    从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 }
    复制代码

      下图就是运行效果。

    ShutdownBlocker

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

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

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

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    LeetCode 123. Best Time to Buy and Sell Stock III (stock problem)
    精帖转载(关于stock problem)
    LeetCode 122. Best Time to Buy and Sell Stock II (stock problem)
    LeetCode 121. Best Time to Buy and Sell Stock (stock problem)
    LeetCode 120. Triangle
    基于docker 搭建Elasticsearch5.6.4 分布式集群
    从零开始构建一个centos+jdk7+tomcat7的docker镜像文件
    Harbor实现容器镜像仓库的管理和运维
    docker中制作自己的JDK+tomcat镜像
    docker镜像制作---jdk7+tomcat7基础镜像
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706631.html
Copyright © 2011-2022 走看看