Windows 7下阻止系統關機


  好長時間不更新博客了,今天終於把畢業設計答辯完了,雖然沒完全做到自己預先設定的目標,但是起碼算是效果出來了。雖然很長時間不更博客,但是訂閱的RSS倒也沒扔下,堅持讀一讀,今天這篇文章就是根據msdn博客的一篇博文寫成的,只是添加了一些代碼,有願意看英文的請移步到這里

  從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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM