windows钩子基础教程 深入探讨.NET中的钩子技术[2]
深入探讨.NET中的钩子技术[2]
三 使用代码
在我们深入开发这个库之前 让我们快速看一下我们的目标 在本文中 我们将开发一个类库 它安装全局系统钩子并且暴露这些由钩子处理的事件 作为我们的钩子类的一个 NET事件 为了说明这个系统钩子类的用法 我们将在一个用C#编写的Windows表单应用程序中创建一个鼠标事件钩子和一个键盘事件钩子
这些类库能用于创建任何类型的系统钩子 其中有两个预编译的钩子 MouseHook和KeyboardHook 我们也已经包含了这些类的特定版本 分别称为MouseHookExt和KeyboardHookExt 根据这些类所设置的模型 你能容易构建系统钩子 针对Win API中任何 种钩子事件类型中的任何一种 另外 这个完整的类库中还有一个编译的HTML帮助文件 它把这些类归档化 请确信你看了这个帮助文件 如果你决定在你的应用程序中使用这个库的话
MouseHook类的用法和生命周期相当简单 首先 我们创建MouseHook类的一个实例
mouseHook = new MouseHook();//mouseHook是一个成员变量
接下来 我们把MouseEvent事件绑定到一个类层次的方法上
mouseHook MouseEvent+=new MouseHook MouseEventHandler(mouseHook_MouseEvent);// private void mouseHook_MouseEvent(MouseEvents mEvent int x int y){ string msg =string Format( 鼠标事件:{ }:({ } { }) mEvent ToString() x y); AddText(msg);//增加消息到文本框}
为开始收到鼠标事件 简单地安装下面的钩子即可
mouseHook InstallHook();
为停止接收事件 只需简单地卸载这个钩子
mouseHook UninstallHook();
你也可以调用Dispose来卸载这个钩子
在你的应用程序退出时 卸载这个钩子是很重要的 让系统钩子一直安装着将减慢系统中的所有的应用程序的消息处理 它甚至能够使一个或多个进程变得很不稳定 因此 请确保在你使用完钩子时一定要移去你的系统钩子 我们确定在我们的示例应用程序会移去该系统钩子 通过在Form的Dispose方法中添加一个Dispose调用
protected override void Dispose(bool disposing) { if (disposing) {if (mouseHook != null) { mouseHook Dispose(); mouseHook = null;}// }}
使用该类库的情况就是如此 该类库中有两个系统钩子类并且相当容易扩充
四 构建库
![windows钩子基础教程 深入探讨.NET中的钩子技术[2]](http://img.zhputi.com/uploads/5837/5837e8e897a6834f5f6a37aece3d4ee162787.jpg)
这个库共有两个主要组件 第一部分是一个C#类库 你可以直接使用于你的应用程序中 该类库 反过来 在内部使用一个非托管的C++ DLL来直接管理系统钩子 我们将首先讨论开发该C++部分 接下来 我们将讨论怎么在C#中使用这个库来构建一个通用的钩子类 就象我们讨论C++/C#交互一样 我们将特别注意C++方法和数据类型是怎样映射到 NET方法和数据类型的
你可能想知道为什么我们需要两个库 特别是一个非托管的C++ DLL 你还可能注意到在本文的背景一节中提到的两篇参考文章 其中并没有使用任何非托管的代码 为此 我的回答是 对!这正是我写这篇文章的原因 当你思考系统钩子是怎样实际地实现它们的功能时 我们需要非托管的代码是十分重要的 为了使一个全局的系统钩子能够工作 Windows把你的DLL插入到每个正在运行的进程的进程空间中 既然大多数进程不是 NET进程 所以 它们不能直接执行 NET装配集 我们需要一种非托管的代码代理 Windows可以把它插入到所有将要被钩住的进程中
首先是提供一种机制来把一个 NET代理传递到我们的C++库 这样 我们用C++语言定义下列函数(SetUserHookCallback)和函数指针(HookProc)
int SetUserHookCallback(HookProc userProc UINT hookID)typedef void (CALLBACK *HookProc)(int code WPARAM w LPARAM l)
SetUserHookCallback的第二个参数是钩子类型 这个函数指针将使用它 现在 我们必须用C#来定义相应的方法和代理以使用这段代码 下面是我们怎样把它映射到C#
private static extern SetCallBackResults SetUserHookCallback(HookProcessedHandler hookCallback HookTypes hookType)protected delegate void HookProcessedHandler(int code UIntPtr wparam IntPtr lparam)public enum HookTypes { JournalRecord = JournalPlayback = // KeyboardLL = MouseLL = };
lishixinzhi/Article/program/net/201311/15484