如何阻止操作系统关闭或注销(阻止操作系统结束自己的进程)

怎么阻止操作系统关闭或注销(阻止操作系统结束自己的进程)

'这是主窗体的子类化过程
Public Function SubWndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

If Msg = WM_QUERYENDSESSION Then
    SubWndProc = 0
    MsgBox "程序还有事情没完"
End If

If Msg <> WM_QUERYENDSESSION Then SubWndProc = CallWindowProc(PrevWndProc, hwnd, Msg, wParam, lParam)
'向以前所有窗口过程发送信息(这是必须的)
End Function

上面的是子类化的代码。当系统要求关或是怎么样的时候,就会向程序发送WM_QUERYENDSESSION消息,但是我看不懂的是MSDN说的返回0(False)系统就不会关闭自己的进程。原文如下:

If an application can terminate conveniently, it should return TRUE; otherwise, it should return FALSE. 

翻译:

如果应用程序可以方便地终止,它应该返回TRUE,否则,它应该返回FALSE。

那么按照他这样说,是不是像我上面的代码那样:

SubWndProc = 0

但是我却发现这样不行,准确说是不彻底。确实,在下面的对话框弹出来的时候,系统确实在等待,可是一旦我单击了对话框的【确定】关闭对话框,系统就会立马注销。两外,如果我不单击【确定】,系统也会在一段时间之后强制注销。能解释一下为什么我返回False了还是会注销呢?(请不要抄MSDN给我,谢谢!!)

或者有没有办法,向系统发送一些什么,直接把用户的注销操作给取消了?

------解决方案--------------------
你看的是 MSDN98 吧,注意最后的Remarks部分,只提到了两个操作系统:Windows NT 和 Windows 95
所以只有在早期的 Windows 中,关机的过程是:通过 WM_QUERYENDSESSION 消息向全体应用询问是否可以关闭,然后再通过 WM_ENDSESSION 消息的 fEndSession 标志通告询问的结果(是否真的要关机)。这样的机制下应用程序的确可以阻止关机;但是无论程序出于故意或编写不当,都有可能导致系统永远无法关机。

于是从 Windows XP 开始,机制变了,只给予一定的等待时间,无论返回 TRUE 或 FALSE 甚至无无响应,最终都会关机。
这时候显示 MsgBox 纯属多余,不如赶紧保存数据。

然后从 Windows Vista 开始,又提供了 ShutdownBlockReasonCreate 和 ShutdownBlockReasonDestroy 函数,用了在关机画面中等待,用户可以决定是否强制关闭。

又:如果用了某些所谓的“优化”软件,可能导致没有等待直接关机。
------解决方案--------------------
引用:
……
运行之后,单击窗体客户区,弹出的对话框显示的是True。可是为什么当我去按注销的时候Windows还是一声不吭地注销了。没有任何反应呢?

对照一下文档 Application Shutdown Changes in Windows Vista

------解决方案--------------------
A)确保用 exe 运行测试
B)分别试试在 WM_QUERYENDSESSION、WM_ENDSESSION 中调用 ShutdownBlockReasonCreate,也许创建时机不对。
C)Spy++ 切换到 Process 模式,找到运行实例的顶级 hWnd,用它调用 ShutdownBlockReasonCreate 试试。
------解决方案--------------------
处理WM_QUERYENDSESSION返回0来禁止关机,还是有条件的,程序必须在HKEY_CURRENT_USER\Control Panel\Desktop\HungAppTimeout设置的时候内响应,否则也起不了作用。
正好之前我帮朋友写过一个禁止关机的DLL,附上代码供参考:
ForbiddenShutdownDll.h

#ifndef _FORBIDDENSHUTDOWNDLL_H_
#define _FORBIDDENSHUTDOWNDLL_H_

#include <Windows.h>

#ifdef FORBIDDENSHUTDOWNDLL_EXPORTS
#define FORBIDDENSHUTDOWNDLL_API extern "C" _declspec(dllexport)
#else
#define FORBIDDENSHUTDOWNDLL_API extern "C" _declspec(dllimport)
#endif

// 回调函数,询问是否可以关机、注销或重启时会调用
// nLogOff:1.准备注销;2.准备重启或关机
typedef void (CALLBACK *pfQueryShutDown)(int nLogOff);

// 获取询问是否可以结束会话消息
// hWnd:捕获系统发往此窗口的询问是否可以结束会话消息
// pFun:回调函数
// bAllowShutDown:是否可以结束会话消息
// hWnd为NULL时取消捕获是否可以结束会话消息
FORBIDDENSHUTDOWNDLL_API bool __stdcall CatchShutDownMessage(HWND hWnd, 
 pfQueryShutDown pFun = NULL, 
 bool bAllowShutDown = false);

#endif // _FORBIDDENSHUTDOWNDLL_H_


ForbiddenShutdownDll.cpp

#define FORBIDDENSHUTDOWNDLL_EXPORTS

#include "ForbiddenShutdownDll.h"

HINSTANCE g_hInst = NULL; // 注册DLL时的实例
HHOOK g_hHook = NULL; // 钩子句柄
pfQueryShutDown g_pfQueryShutDown = NULL; // 回调函数指针
HWND g_hWnd = NULL; // 窗口句柄
WNDPROC g_oldWndProc = NULL; // 窗口过程
bool g_bAllowShutDown = true; // 是否允许关机、注销或重启

// 卸载监控钩子
bool StopHook()
{
bool bRet = false;
if (NULL != g_hHook)
{
if (FALSE != UnhookWindowsHookEx(g_hHook))
{
g_hHook = NULL;
bRet = true;
}
}
else
{
bRet = true;
}

return bRet;
}

LRESULT CALLBACK CallWindowProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PCWPSTRUCT pcw = (PCWPSTRUCT)lParam; 

if(nCode>=0 && pcw && pcw->hwnd)
{
if (WM_QUERYENDSESSION == pcw->message) 
{
if (NULL != g_hWnd && g_hWnd == pcw->hwnd)