架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8093|回复: 0

[技巧] C#编程技巧之钩子函数的使用——SetWindowsHookEx

[复制链接]
发表于 2019-2-7 21:12:59 | 显示全部楼层 |阅读模式
总所周知:C#是.NET Framework平台的相伴语言,用它本身的类库和编译器提供的方法是无法实现全局钩子的。但实际上对于非托管代码的调用在C#中是成立的,使用DllImport属性可以引用非托管代码类库中的方法。钩子函数存在于user32.dll中,函数原型如下:

  HHOOK WINAPI SetWindowsHookEx(

    __in int idHook,

    __in HOOKPROC lpfn,

    __in HINSTANCE hMod,

    __in DWORD dwThreadId);

  使用它可以向操作系统(Windows)注册一个特定类型的消息拦截处理方法,例如我们可以注册一个拦截全局键盘消息的钩子,那么所有的键盘按下、抬起事件都可以被我们感知和处理(不排除有前端钩子将消息丢弃的情况)。

  我们在C#中可以如下声明来引用这个函数:

    [DllImport("user32.dll")]
        public static extern int SetWindowsHookEx(
            HookType idHook,
            HookProc lpfn,
            IntPtr hInstance,
            int threadId
            );

  值得一提的是上面的HookType和HookProc是我自定义的类型,这无关紧要(因为程序运行时传递的是内存地址嘛),但必须符合一定规范。

  函数的参数从上到下依次为:

     idHook钩子类型,此处用整形的枚举表示
       lpfn钩子发挥作用时的回调函数
       hInstance应用程序实例的模块句柄(一般来说是你钩子回调函数所在的应用程序实例模块句柄)
       threadId与安装的钩子子程相关联的线程的标识符

  钩子的类型有以下几种:
我们一般会使用13拦截键盘消息,14拦截鼠标消息。

  回调函数的声明我们在C#里需要用到委托,声明如下:
    public delegate int HookProc(int nCode, int wParam, IntPtr lParam);

  从上而下参数意义为:nCode钩子链传递回来的参数,0表示此消息(被之前的消息钩子)丢弃,非0表示此消息继续有效

            wParam消息参数

            lParam消息参数

  值得一提的是wParam和lParam在不同的消息类型中是不一样的类型,不过wParam的类型大概可以用下面的枚举表示:
而lParam一般被封装为结构,因消息类型而异,如下的两个结构分别是鼠标和键盘消息的lParam结构:
当我们了解了以上信息时,我们就基本了解了钩子函数的C#实现了,然后注意几个问题就好:

    1.钩子对资源占用很多,不用时应及时取消掉,这个需要使用UnhookWindowsHookEx函数

    2.处于礼貌,钩子应返回下一个钩子的处理结果,而不是单一地将当前钩子的处理结果返回(使用CallNextHookEx调用下一个钩子,由于钩子是先设置后生效,所以应该如此来保证钩子链的正常传递)

    3.钩子函数参数中的hInstance是只当前钩子的回调函数在哪儿,一定要给出正确地址

    4.因为使用了委托,应该保证委托的内存地址(对方法的引用)不会垃圾回收,否则在钩子执行时会出现异常



  大家可以下载我写的示例程序,不过我的程序有以下的地方需要主要:

    1.我将钩子的实现屏蔽了,只对外开放了键盘和鼠标的消息拦截和处理(使用方式和C#的WinForm鼠标键盘事件一致),你可以开放出来其它的

    2.我将钩子设计为单例模式,你可以取消

    3.由于对操作系统有一定侵入,杀毒软件可能会报出有风险

    4.代码写得很糟糕,凑合着看吧……



  最后说一句:编程技术和语言的关系不大,语言的区别在于它们的编译器和他们的使用者,使用C的人不能说一定比使用Java的高等,而技术也不一定体现在指针、矩阵、数据结构上,只要对计算机原理、编译原理、操作系统原理等了解的人都明白。当然,大家有自己的喜欢的语言和惯用的编程手法固然是很好的。





上一篇:纯C#钩子实现
下一篇:【匠石微信多开】微信免扫码登录|无限多开|保存登录配置
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2024-4-26 06:42

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表