• C# 封装一个钩子类


    利用C#设置钩子函数,并封装成类。如果想要实现全局钩子的话,必须将实现的代码封装到类库里。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Reflection;
    using System.Diagnostics;
    using System.Windows.Forms;
    
    namespace PublicHook
    {
        /// <summary>
        ///存放回调函数的委托
        /// </summary>
        public delegate int HOOKPROC(int nCode, IntPtr wParam, IntPtr lParam);
        public enum HookType
        {
            WH_KEYBOARD = 2,        //私有键盘钩子
            WH_EKYBOARD_LL = 13,    //全局键盘钩子
            WH_MOUSE = 7,           //私有鼠标钩子
            WH_MOUSE_LL = 14        //全局鼠标钩子
        }
    
        public abstract class hook
        {
            //设置钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int SetWindowsHookEx(HookType idHook, HOOKPROC lpfn, IntPtr hInstance, int threadId);
            //取下钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(int idHook);
            //获取当前线程一个唯一的线程标识符
            [DllImport("kernel32")]
            public static extern int GetCurrentThreadId();
            //传递消息给下一个钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
            //获取一个应用程序或动态链接库的模块句柄
            [DllImport("kernel32.dll")]
            public static extern IntPtr GetModuleHandle(string name);
    
            /// <summary>
            /// 钩子处理委托
            /// </summary>
            public HOOKPROC proc;
            /// <summary>
            /// 钩子类型
            /// </summary>
            public HookType type;
            /// <summary>
            /// 钩子的句柄
            /// </summary>
            public int hHook = 0;
    
            public hook(HOOKPROC proc, HookType type)
            {
                this.proc = proc;
                this.type = type;
            }
            //设置回调函数
            public void SetProc(HOOKPROC proc)
            {
                this.proc = proc;
            }
    
            public abstract int SetWindowsHookEx();
            public virtual void UnhookWindowsHookEx()
            {
                bool retKeyboard = true;
                //当前钩子句柄不为空,卸载钩子
                if (hHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hHook);
                    hHook = 0;
                }
                if (!retKeyboard)
                    throw new Exception("UnhookWindowsHookEx failed.");
            }
        }
    
        public class PublicKBHook : hook
        {
            public PublicKBHook(HOOKPROC proc)
                : base(proc, HookType.WH_EKYBOARD_LL)
            { }
           
            public override int SetWindowsHookEx()
            {
                if (hHook == 0)
                    hHook = SetWindowsHookEx(this.type, this.proc,
                        GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
                return hHook;
            }
    
            //Hook结构
            [StructLayout(LayoutKind.Sequential)]
            public class HookStruct
            {
                public int vkCode;
                public int scanCode;
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
            /// <summary>
            ///回调函数,屏蔽除了回车和tab之外的所有键盘消息
            /// </summary>
            public int MyKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam)
            {
                if ( nCode >= 0 )                  
                {
                    HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure((IntPtr)lParam, typeof(HookStruct));
                    //如果按下了回车,则将消息传给下一个钩子
                    if ((Keys)hookStruct.vkCode == Keys.Enter ||
                        (Keys)hookStruct.vkCode == Keys.Tab)
                        return CallNextHookEx(hHook, nCode, wParam, lParam);
                    //后门
                    if ((Keys)hookStruct.vkCode == Keys.F1)
                        UnhookWindowsHookEx( hHook );
                }
    
                return 1;
            }
        }
    
        public class PrivateKBHook : hook
        {
            public PrivateKBHook(HOOKPROC proc)
                : base(proc, HookType.WH_KEYBOARD)
            { }
    
            public override int SetWindowsHookEx()
            {
                if (hHook == 0)
                    hHook = SetWindowsHookEx(this.type, this.proc, IntPtr.Zero, GetCurrentThreadId());
                return hHook;
            }
        }
    
        public class PublicMouseHook : hook
        {
            public PublicMouseHook(HOOKPROC proc)
                : base(proc, HookType.WH_MOUSE_LL)
            { }
    
            public override int SetWindowsHookEx()
            {
                if (hHook == 0)
                    hHook = SetWindowsHookEx(this.type, this.proc,
                        GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
                return hHook;
            }
    
            /// <summary>
            /// 屏蔽除了鼠标移动之外的鼠标消息
            /// </summary>
            public int MyMouseProc(int nCode, IntPtr wParam, IntPtr lParam)
            {
                //当wParam = 0x0200 时,进行鼠标移动操作
                //直接将消息传递给下一个钩子
                if (wParam == (IntPtr)0x0200)
                    return CallNextHookEx(hHook, nCode, wParam, lParam);
    
                return 1;
            }
        }
    
        public class PrivateMouseHook : hook
        {
            public PrivateMouseHook(HOOKPROC proc)
                : base(proc, HookType.WH_MOUSE)
            { }
    
            public override int SetWindowsHookEx()
            {
                if (hHook == 0)
                    hHook = SetWindowsHookEx(this.type, this.proc, IntPtr.Zero, GetCurrentThreadId());
    
                return hHook;
            }
        }
    }

    调用代码:

                //钩子句柄
                int hKBHook = 0, hMouseHook = 0;
                //设置全局键盘钩子
                PublicKBHook myKBHook = new PublicKBHook(null);
                myKBHook.SetProc(myKBHook.MyKeyboardProc);
                hKBHook = myKBHook.SetWindowsHookEx();      

    卸载钩子:

    //撤销钩子
                    myKBHook.UnhookWindowsHookEx();
  • 相关阅读:
    PHP使用CURL详解
    PHP中使用sleep函数实现定时任务实例分享
    (实用篇)PHP ftp上传文件操作类
    php Pthread 多线程基本介绍
    用PHP发送POST请求
    面向对象【day08】:类的起源与metaclass(二)
    面向对象【day07】:面向对象使用场景(十)
    面向对象【day07】:知识点回顾(十一)
    面向对象【day07】:析构函数(六)
    面向对象【day07】:类的继承(七)
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5305837.html
Copyright © 2020-2023  润新知