系统钩子在C#的声明

将WINAPI的WINDOWSHOOKEX封装成C#的类,某些钩子类型只能用C/C++写的DLL才能运行,如CBT钩子,有些使用C#写的方法就能实现如:WH_KEYBOARD_LL ,WH_MOUSE_LL

因为IntPtr相当于一个VOID指针,因此在C#能够指向任何一个钩子类型的结构。用 Marshal 类的StructureToPtr,就能将定义的结构包装给IntPtr类型

 

 

 

 

using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Diagnostics;


namespace FengCreateCLRDll {


    namespace Win32API {


        namespace WindowsHookEx{

        /// <summary>
        /// 只读的静态成员,用来表示钩子的类型,这个类不存储某些钩子类型,
        /// 可以在WinUser.h中查找
        /// </summary>
        public class HookType {
            public static readonly int WH_CALLWNDPROC = 4;
            public static readonly int WH_JOURNALRECORD = 0;
            public static readonly int WH_KEYBOARD = 2;
            public static readonly int WH_GETMESSAGE = 3;
            public static readonly int WH_CBT = 5;
            public static readonly int WH_SYSMSGFILTER = 6;
            public static readonly int WH_MOUSE = 7;
            public static readonly int WH_DEBUG = 9;
            public static readonly int WH_SHELL = 10;
            public static readonly int WH_FOREGROUNDIDLE = 11;
            public static readonly int WH_CALLWNDPROCRET = 12;
            /// <summary>
            /// LOWLEVEL键盘钩子类型
            /// </summary>
            public static readonly int WH_KEYBOARD_LL = 13;
            /// <summary>
            /// LOWLEVEL鼠标钩子类型
            /// </summary>
            public static readonly int WH_MOUSE_LL = 14;
            private HookType() { }

        };

 

        /// <summary>
        /// 处理钩子回调的函数。用户提供相对应的函数,作为这个委托的处理程序
        /// </summary>
        /// <param name="nCode">当这个参数大于0时才处理回调函数</param>
        /// <param name="wParam">钩子消息,在不同钩子有不同的处理</param>
        /// <param name="lParam">指向一个结构,可由Marshal.PtrToStructure转换成特定类型的结构</param>
        /// <returns>如果要拦截某种类型钩子的消息,返回IntPtr.Zero或者其他处理;
        /// 否则应调用CallNextHookEx作为返回值</returns>
        public delegate IntPtr CallbackWindowsHookEx(int nCode,IntPtr wParam,IntPtr lParam);

        /// <summary>
        /// LOWlEVEL键盘钩子,回调函数的lParam参数指向的结构
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct KBDLLHOOKSTRUCT {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public IntPtr dwExtraInfo;
        };
        /// <summary>
        /// LOWlEVEL鼠标钩子,回调函数的lParam参数指向的结构
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct MSLLHOOKSTRUCT {
            public POINT pt;
            public int mouseData;
            public int flags;
            public int time;
            public IntPtr extraInfo;
        };
        /// <summary>
        /// 表示鼠标指针所在的X-Y坐标上的点
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT {
            public int x;
            public int y;
        };


        /// <summary>
        /// .net实现WINDOWS钩子的定义类
        /// </summary>
        public class CLRSetWindowsHookEx_Define {

            /*typedef struct _MYHOOKDATA
{
    int nType;
    HOOKPROC hkprc;
    HHOOK hhook;
} MYHOOKDATA;
 
MYHOOKDATA myhookdata[NUMHOOKS]; */
            //例子通过数组的索引查找MYHOOKDATA结构的数据
            //通过值建类型检索MYHOOKDATA结构××××××××××××××××××××
            /// <summary>
            /// 安装钩子函数
            /// </summary>
            /// <param name="idHook">钩子类型,可由FengCreateCLRDll.Win32API.WindowsHookEx.HookType
            /// 静态字段获取指定的钩子类型</param>
            /// <param name="lpfn">回调函数,用户必须定义一个跟FengCreateCLRDll.Win32API.WindowsHookEx.CallbackWindowsHookEx
            /// 相同签名档函数</param>
            /// <param name="hMod">模块句柄,该模块包含有CallbackWindowsHookEx回调的处理函数,
            /// 如果指定了ThreadId参数,可为空值</param>
            /// <param name="ThreadId">线程的ID,该线程关联钩子回调函数,如果设为0,回调函数同
            /// 相同桌面下的所有的存在的、正在运行的线程相关联</param>
            /// <returns>成功返回钩子的句柄,否则为空值</returns>
            [DllImport("user32.dll", SetLastError = true)]
        public     static extern IntPtr SetWindowsHookEx(
                    int idHook,
                   CallbackWindowsHookEx lpfn,
                     IntPtr hMod,
                     int ThreadId
                     );


            /// <summary>
        /// 作为回调函数的返回值使用
            /// </summary>
            [DllImport("user32.dll", SetLastError = true)]
            public  static extern IntPtr CallNextHookEx(
                 IntPtr hhk,
                 int nCode,
                 IntPtr wParam,
          IntPtr  lParam
                 );
            /// <summary>
            /// 移除钩子函数
            /// </summary>
            [DllImport("user32.dll", SetLastError = true)]
         public    static extern int UnhookWindowsHookEx(IntPtr hhk);


            /// <summary>
         /// 获取指定模块的句柄,在这里用做SetWindowsHookEx函数的hMod参数
            /// </summary>
            [DllImport("kernel32.dll", SetLastError = true)]
         public   static extern IntPtr GetModuleHandle(string lpModulename);

    };

 


            /// <summary>
    /// 该类将某一种钩子类型实例化,当不用时应调用Dispose函数移除钩子,该类不会自动清除钩子
            /// </summary>
            public  sealed class CLRSetWindowsHookEx_Ins:IDisposable {
                private IntPtr hhook = IntPtr.Zero;//返回钩子的句柄
                /// <summary>
                /// 获取当前实例的钩子的句柄,即SetWindowsHookEx的返回值
                /// </summary>
                public IntPtr HHook {
                    get { return this.hhook; }
                }
                /// <summary>
                /// 用来存储CallbackWindowsHookEx回调的字段,这样用户不必在实现代码的地方,实例化
                /// 一个CallbackWindowsHookEx类型的变量,使用这个字段可防止回调实例被过早的回收。
                /// 当然,用户也可另行实例化一个CallbackWindowsHookEx变量,然后用GC.KeepAlive保护该变量被
                /// 过早的回收。另:不可使用多路广播委托,只能持有一个相同签名档方法.
                /// </summary>
                public CallbackWindowsHookEx HookProc=null;
                /// <summary>
                /// 该构造函数,同SetWindowsHookEx函数,将其返回值包装在此类中
                /// </summary>
                /// <param name="hooktype">可由FengCreateCLRDll.Win32API.WindowsHookEx.HookType获取钩子的类型</param>
                /// <param name="hookproc">CallbackWindowsHookEx回调函数,用户可在现实代码处使用HookProc字段</param>
                public CLRSetWindowsHookEx_Ins(int hooktype, CallbackWindowsHookEx hookproc
                    , IntPtr hMod, int ThreadId) {
                    this.hhook = CLRSetWindowsHookEx_Define.SetWindowsHookEx(hooktype,
                     hookproc  , hMod, ThreadId);

                }
                /// <summary>
                /// 该构造函数用来表示钩子只能在当前进程中使用,忽略了hMod和ThreadId参数
                /// </summary>
                /// <param name="hooktype">可由FengCreateCLRDll.Win32API.WindowsHookEx.HookType获取钩子的类型</param>
                /// <param name="hookproc">CallbackWindowsHookEx回调函数,用户可在现实代码处使用HookProc字段</param>
                public CLRSetWindowsHookEx_Ins(int hooktype, CallbackWindowsHookEx hookproc) {
                    this.hhook = CLRSetWindowsHookEx_Define.SetWindowsHookEx(
                        hooktype, hookproc,
                        CLRSetWindowsHookEx_Define.GetModuleHandle(
                        Process.GetCurrentProcess().MainModule.FileName),
                        0);
                }
                    /// <summary>
                    /// 该方法用来移除实例化该类的所安装的钩子,当不再使用该类时,必须调用
                    /// 这个方法移除钩子
                    /// </summary>
                public void Dispose() {
                    GC.KeepAlive(this.hhook);
                    if(!((int)this.hhook == -1 || (int)this.hhook == 6)){//错误、无效句柄
                      
                    if(this.hhook != IntPtr.Zero) {
                        CLRSetWindowsHookEx_Define.UnhookWindowsHookEx
                    (this.hhook);
                        this.hhook = IntPtr.Zero;
                    }
                    }
                        GC.KeepAlive(this.HookProc);
                        if(this.HookProc!=null){
                            this.HookProc = null;
                }

                    }
               
                ~CLRSetWindowsHookEx_Ins() { }
        
             
            };

 

 

 

        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值