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