系统钩子应用--如何通过编程实现禁止Windows系统关机?
1 关于系统钩子
1) 钩子根据其对消息监视范围的不同而分为系统全局钩子和线程局部钩子两大类,其中线程局部钩子只能监视本进程中某个指定的线程,而全局钩子则可对在当前系统下运行的所有线程进行监视。
2)线程钩子可以看作是全局钩子的一个子集,全局钩子虽然功能强大但同时实现起来也比较烦琐:其钩子函数的实现必须封装在独立的动态链接库(DLL)中才可以被各种相关联的应用程序所使用。
注:关于钩子更多的实际定义,读者可以查看百度相关资料学习,限于篇幅,本文不详细解释。
2实现禁止关机的钩子方法--系统钩子需要在一个DLL中实现
2.1 在DLL中需要定义与程序共享的数据
#pragma data_seg("mydata")
HHOOK hSysHook = NULL; //安装的鼠标钩子句柄
HINSTANCE hMod = NULL; // DLL实例句柄
HWND hClientWnd = NULL;//客户端的窗口句柄
#pragma data_seg()
2.2在DLL中需要输出的3个函数的源代码如下:
//系统钩子函数:
SYSHOOK_DLL_API LRESULT CALLBACK SysHookProc(int nCode ,WPARAM wParam,LPARAM lParam)
{
//系统关机、注销会发送的消息:WM_QUERYENDSESSION , WM_ENDSESSION
if(nCode == WM_QUERYENDSESSION || nCode == WM_ENDSESSION )
{
PostMessage(hClientWnd,nCode,wParam,lParam);
return false;
}
else
{
return CallNextHookEx(hSysHook, nCode,wParam,lParam);
}
}
//启动系统钩子函数:
SYSHOOK_DLL_API bool StartSysHook(HINSTANCE hMod,HWND hWnd)
{
if(hMod != NULL)
{
hSysHook = SetWindowsHookEx(WH_SYSMSGFILTER,SysHookProc, hMod, 0); //创建钩子
if(hSysHook != NULL)//检测钩子的有效性
{
hClientWnd = hWnd;
return true;
}
}
return false;
}
//停止系统钩子安装:
SYSHOOK_DLL_API bool StopSysHook()
{
bool bRet = false;
if(hSysHook!=NULL)
{
bRet = (UnhookWindowsHookEx(hSysHook) != 0); //卸载钩子
if(bRet)
{
hSysHook = NULL;
}
}
return bRet;
}
2.3在客户端程序定义的操作(基于对话框的MFC程序)
2.3.1创建系统钩子--调用DLL输出函数实现:
//安装系统钩子函数:
HMODULE hMod = LoadLibrary("SysHookDll.dll");//系统钩子实现相关的3个函数所在的DLL
m_bHook = StartSysHook(hMod,m_hWnd); //调用DLL输出函数启动钩子
if(!m_bHook)
{
AfxMessageBox("安装系统钩子失败!",MB_OK);
}
2.3.2对话框需要处理WM_QUERYENDSESSION消息
BOOL CSysHookDlg::OnQueryEndSession()
{
if (!CDialog::OnQueryEndSession())
return FALSE;
//将拦截的关机消息,在调用窗口的列表上显示:
CTime time = CTime::GetCurrentTime();
CString strMsg;
strMsg.Format("收到关机消息:WM_QUERYENDSESSION!,时间:-:-:-",
time.GetHour(),time.GetMinute(),time.GetSecond());
m_MsgList.AddString(strMsg);
return false; //注意一定需要返回false,否则无法禁止关机!
}
3测试
1)在Window XP系统下,启动程序,经测试,XP无法进行关机;
2)关闭程序,XP可以正常进行关机。
需要源代码的朋友,请给我留言!