C#键盘钩子之局部钩子和全局钩子

c#-全局键盘钩子 using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics; namespace WebClick_Tool { public cla 阅读详情

最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。
因为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处都是。
大部分网上参考文章都只是展示了全局钩子的写法,而线程钩子的写法和介绍相对少一些,特别是关键语句上如果定义的不正确是没有任何效果的,在自己反复尝试后决定留下一个正确的版本分享出来
代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace AssistToolSet.Util
{
    /// <summary>
    /// 键盘钩子类
    /// </summary>
    public class Hook
    {
        public delegate int HookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam);
        public enum WH_CODE : int
        {
            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            /// <summary>
            /// 进程钩子
            /// </summary>
            WH_KEYBOARD = 2,

            /// <summary>
            /// 底层键盘钩子 全局钩子就是用这个

            /// </summary>
            WH_KEYBOARD_LL = 13,
        }

        public enum HC_CODE : int
        {
            HC_ACTION = 0,
            HC_GETNEXT = 1,
            HC_SKIP = 2,
            HC_NOREMOVE = 3,
            HC_NOREM = 3,
            HC_SYSMODALON = 4,
            HC_SYSMODALOFF = 5
        }

        /// <summary>
        /// 安装钩子
        /// </summary>
        [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr SetWindowsHookEx(WH_CODE idHook, HookProc lpfn, IntPtr pInstance, uint threadId);

        /// <summary>
        /// 卸载钩子
        /// </summary>
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
        /// <summary>
        /// 传递钩子
        /// </summary>
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(IntPtr pHookHandle, WH_CODE nCodem, Int32 wParam, IntPtr lParam);

        /// <summary>
        /// 获取全部按键状态
        /// </summary>
        /// <param name="pbKeyState"></param>
        /// <returns>非0表示成功</returns>
        [DllImport("user32.dll")]
        public static extern int GetKeyboardState(byte[] pbKeyState);

        /// <summary>
        /// 获取程序集模块的句柄
        /// </summary>
        /// <param name="lpModuleName"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        /// <summary>
        /// 获取当前进程中的当前线程ID
        /// </summary>
        /// <returns></returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern uint GetCurrentThreadId();

        #region 私有变量

        private byte[] mKeyState = new byte[256];
        private Keys mKeyData = Keys.None; //专门用于判断按键的状态

        /// <summary>
        /// 键盘钩子句柄
        /// </summary>
        private IntPtr mKetboardHook = IntPtr.Zero;

        /// <summary>
        /// 键盘钩子委托实例
        /// </summary>
        private HookProc mKeyboardHookProcedure;

        #endregion

        #region 键盘事件

        public event KeyEventHandler OnKeyDown;
        public event KeyEventHandler OnKeyUp;

        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public Hook()
        {
            GetKeyboardState(this.mKeyState);
        }

        ~Hook()
        {
            UnInstallHook();
        }

        /// <summary>
        /// 键盘钩子处理函数
        /// </summary>
        private int KeyboardHookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam)
        {
        /*全局钩子应该这样设定
         KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
        */
            // 定义为线程钩子时,wParam的值是击打的按键,与Keys里的对应按键相同
            if ((nCode == (int)HC_CODE.HC_ACTION) && (this.OnKeyDown != null || this.OnKeyUp != null))
            {
                mKeyData = (Keys)wParam;
                KeyEventArgs keyEvent = new KeyEventArgs(mKeyData);
                //这里简单的通过lParam的值的正负情况与按键的状态相关联
                if (lParam.ToInt32() > 0 && this.OnKeyDown != null)
                {
                    this.OnKeyDown(this, keyEvent);
                }
                else if (lParam.ToInt32() < 0 && this.OnKeyUp != null)
                {
                    this.OnKeyUp(this, keyEvent);
                }
            }
            if (ShortcutManagement.s_bHotkeyUsed)
            {
                ShortcutManagement.s_bHotkeyUsed = false;
                return 1;
            }

            return CallNextHookEx(this.mKetboardHook, nCode, wParam, lParam);
        }
        /// <summary>
        /// 安装钩子
        /// </summary>
        /// <returns></returns>
        public bool InstallHook()
        {
            //线程钩子时一定要通过这个取得的值才是操作系统下真实的线程
            uint result = GetCurrentThreadId();

            if (this.mKetboardHook == IntPtr.Zero)
            {
                this.mKeyboardHookProcedure = new HookProc(this.KeyboardHookProc);
                //注册线程钩子时第三个参数是空
                this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD, this.mKeyboardHookProcedure, IntPtr.Zero, result);
                /*
                如果是全局钩子应该这样使用
                this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD_LL, mKeyboardHookProcedure,GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
                */
                if (this.mKetboardHook == IntPtr.Zero)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 卸载钩子
        /// </summary>
        /// <returns>true表示成功 </returns>
        public bool UnInstallHook()
        {
            bool result = true;
            if (this.mKetboardHook != IntPtr.Zero)
            {
                result = UnhookWindowsHookEx(this.mKetboardHook) && result;
                this.mKetboardHook = IntPtr.Zero;
            }
            return result;
        }
    }

}

通过这次认知,意识到,以后如果要做这些接触相关的api的时候,我们应该尽量去查官方文档,而不是一开始就是查看别人的博客。应该以官方文档为主。一定要记住键盘钩子事件。32位和64位的系统不一样。

C# 实现系统级鼠标和键盘钩子函数Demo Windows Forms是.NET Framework中用于开发Windows桌面应用程序的图形用户界面(GUI)库。它是早期.NET平台应用程序的主要开发方式之一。通过Windows Forms,开发者能够快速创建丰富的交互式应用程序,其功能包括窗口创建、事件处理、控件管理等。事件在Windows应用程序中扮演着至关重要的角色,它们是应用程序与用户交互的桥梁。事件可以是由用户的动作(如鼠标点击或键盘按键)引起的,也可以是由系统消息(如定时器超时或窗口重绘)引起的。 阅读详情

相关推荐

C#实现键盘全局钩子屏蔽按键功能案例

C#(发音为“看#”或“西#”)是一种现代、面向对象的编程语言,由微软公司于2000年随.NET平台一同发布。它是由Anders Hejlsberg主导设计,他之前也是Turbo Pascal、Delphi和VisiCalc的首席架构师。C#语言的设计融合了C++的强大能力和Visual Basic的简单易用性,旨在为开发Windows应用程序提供一种高效、安全且类型安全的编程手段。在Windows操作系统中,钩子(Hook)是一种特殊的程序,它允许开发者介入系统消息的传递过程中。

weixin_29363791的博客 1075

C# 全局键盘钩子的简单实现

WPF的全局键盘钩子,自己实现的代码

weixin_43152819的博客 969

C#全局钩子实战:键盘监听与文件框内容获取技术

P/Invoke 是 .NET 提供的一种机制,允许托管代码调用非托管函数。这些非托管函数通常存在于Windows系统的DLL中,例如user32.dll和gdi32.dll等。对于全局钩子的实现,P/Invoke 是必不可少的桥梁,因为核心函数如和都是Windows API函数。P/Invoke 的作用包括:声明非托管函数的签名将C#中的数据类型映射为Windows API期望的数据类型控制调用约定(Calling Convention)

weixin_31749299的博客 953

C#键盘钩子(Hook)拦截器的使用

钩子过程是一个回调函数,用于处理被拦截的键盘事件。在C#中,可以通过委托来定义钩子过程。

故事不长丨的博客 4661

Visual Studio 2010实现全局键盘鼠标钩子教程

在现代软件开发中,全局键盘鼠标钩子技术是构建各种应用程序的重要组成部分,它允许开发者捕获并处理系统级别的输入事件。本章节将为读者提供一个全局键盘鼠标钩子技术的概览,并讨论其工作原理以及在软件开发中的应用范围。钩子(Hook)技术是一种用于改变或增强操作系统、应用程序或软件库行为的技术。在Windows操作系统中,钩子是通过钩子链(Hook Chain)实现的,它允许系统或应用程序截获并处理其他进程的消息和事件。

weixin_36303305的博客 984

ADS中使用Momentum进行电源完整性分析示例

这个应用可以帮助工程师用更快的时间使用ADS Momentum完成PDN分析。该应用描述了利用ADS Momentum RF模拟器进行PDN分析的方法,大大缩短了计算时间。 该分析主要应用与高速数字设计。 在此应用中使用了以下ADS特性: ADS设计流程集成(ADFI)。 电磁协同仿真。 Momentum仿真。 仿真流程如下: 在Allegro中创建ADFI文件 要将Alleg...

zb6075_lb的专栏 7009

C语言中钩子函数使用讲解

钩子(hook)又称钩子函数,是在一个有序的周期中的某些特殊时刻,系统内部预先设置好的函数,当系统周期到达指定时刻 会自动执行该'钩子'。钩子函数的函数体内容由开发者编写,这绐了幵发者在不同阶段做某些处理的机会。

咸鱼弟的博客 9500

ENVI 5.6保姆级教程:高分七号DLC影像从打开到融合的完整流程(附避坑指南)

本文详细介绍了ENVI 5.6处理高分七号DLC影像的完整流程,包括环境准备、数据解压、正射校正、图像融合等关键步骤。特别针对国产卫星数据处理的独特挑战,提供了实用的避坑指南和优化技巧,帮助用户高效完成光学影像的预处理和质量提升。

weixin_33269743的博客 382

【转】C#键盘钩子之局部钩子

这篇文章也是转载的,如果作者不希望被转载,请联系我删除,谢谢。 因为之前没看懂,所以特地转载了,留着自己再次学习使用。 最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。     因为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处...

sunstar8921的博客 813

Xilinx ERNIC RoCEv2 FPGA实现与QP队列深度解析

本文深入解析Xilinx ERNIC RoCEv2在FPGA上的实现,重点剖析QP队列对的管理机制与深度优化策略。通过Verilog代码示例和工程实战,详细介绍了如何实现高吞吐量、低延迟的RDMA硬件卸载方案,为金融交易和数据中心应用提供性能优化指导。

solidity8miner的博客 877

Win10家庭版中文用户名改英文全攻略:从注册表到环境变量一步不落

本文详细介绍了Windows 10家庭版中文用户名改为英文的完整流程,包括注册表编辑、环境变量调整等关键步骤。通过激活管理员账户、重命名用户文件夹、修改注册表键值等操作,彻底解决因中文路径导致的软件兼容性问题,并提供常见错误解决方案和系统维护建议。

weixin_29227425的博客 427

C#通过键盘钩子获取数据

C#通过键盘钩子获取数据 前言 在做关于使用USB刷卡器、扫码枪等项目的开发时,有可能需要通过键盘钩子去获取刷卡器、扫码枪获取的数据,当然,如果设备是串口、或者非系统独占设备的USB,可以采用串口通信、HID设备读写去获取数据。 本文是记录了C#如何通过键盘钩子去获取刷卡器读取上来的数据。 一、项目背景 需要获取刷卡器读到的卡号,然后根据卡号从客户的WebService中获取数据。所以第一步工作是...

Flora1992的博客 3115

2026.5.3:Ubuntu26.04下uv所需的环境变量pyproject.toml

本文档提供了Python开发环境的配置指南。主要包括: 设置环境变量(HF_ENDPOINT、UV_PYTHON_INSTALL_MIRROR等) 创建pyproject.toml配置文件,定义项目元数据(名称、版本等) 指定依赖项(torch系列库)及其安装源(PyTorch官方CUDA 12.8镜像) 配置Python版本要求(>=3.13,<3.14) 设置平台限制(Linux/Windows) 该配置适用于需要PyTorch CUDA 12.8支持的项目开发环境搭建。

拥抱具身智能,昇腾Ascend C 588

C#全局钩子和局部钩子记录

源自:https://blog.youkuaiyun.com/programvae/article/details/80292076 最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。 因为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处都...

weixin_30706691的博客 259

大模型LoRA微调调参的实战技巧(持续更新)

本文主要介绍了大模型LoRA微调调参的实战技巧,希望对学习大语言模型的同学们有所帮助。 文章目录 1. 前言 2. 实战技巧

herosunly的博客 20万+

【Bluetooth|蓝牙开发】二、蓝牙开发入门

蓝牙,是一种利用低功率无线电,支持设备短距离通信的无线电技术,能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行无线信息交换,蓝牙工作在全球通用的2.4GHz ISM(即工业、科学、医学)频段,使用IEEE802.11协议。

Donge's Blog 1万+

钩子函数和键盘记录

<br />钩子必备函数<br /><br />要安装钩子,必须用SetWindowsHookEx函数,函数原型如下:<br /><br />HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);<br /><br />idhook参数指定钩子的类型,钩子的类型如下:<br /><br /> WH_CALLWNDPROC每当调用SendMessage函数时,函数将消息发送给目标窗口时首先调用钩子函

irainbow5的专栏 706

【YOLOv11改进- 主干网络】YOLOv11+RepViT: 从ViT的角度重新审视Mobile的CNN助力YOLOv11有效涨点;

本文给大家带来的改进内容是在YOLOv11中更换主干网络为RepViT,助力YOLOv11有效涨点,论文通过集成轻量级 ViT 的高效架构设计,逐步增强了标准轻量级 CNN(即 MobileNetV3)的移动友好性。这最终产生了一个新的纯轻量级 CNN 系列的主干网络。

qq_41304809的博客 785

C# 实现屏幕键盘 (ScreenKeyboard)

要实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子,也就 是系统范围的钩子。 什么是钩子(Hook) 钩子(Hook)是Windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先 启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通 过系统调用,把它挂入系统。每当特定的消息发...

weixin_33682719的博客 761

从GBA游戏ROM文件里提取MIDI文件

从GBA游戏ROM文件里提取MIDI文件

jdk-8u51-windows64X

jdk-8u51-windows64X

用钩子(hook)实现C#的屏幕键盘效果

        要实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子,也就是系统范围的钩子。什么是钩子(Hook)       钩子(Hook)是Windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有

程序员天空 2622

阿里云盘福利码更新[源码]

本文提供了2025年8月最新的阿里云盘福利码,用户可通过兑换码获得200GB额外存储空间。文章详细介绍了兑换步骤:登录阿里云盘App,进入个人中心的“福利社”,输入福利码并确认即可。同时提醒用户福利码数量有限且有效期不定,建议尽快使用。作者承诺每月更新福利码,并鼓励读者关注和收藏文章以获取最新信息。文末附有最新福利码示例,帮助用户轻松扩容云盘存储空间。

局部钩子能防全局钩子吗_一分钟讲解HOOK技术,c++全局钩子打造键盘记录器!...

学习编程也有一段时间了,闲暇之余编写了这个程序,以此来纪念完成的课程设计。源代码在压缩包里面,程序是使用vs2017编写的。源代码网上也有大部分是使用 c#,c++写的,看的头晕,就结合c,重写了下。 使用说明: 需要这两个文件,文件在Release目录下(解压后放在同一个文件夹下面才能运行) 文件: KeyboardRecorder.exe 文件: Keyboard.dll 1、双击Keyb...

weixin_39883440的博客 216

itunes功能示例完整C++代码

itunes登录完整C++代码

C#键盘钩子

http://www.pinvoke.net/default.aspx        HookProc hookProc = null;         IntPtr hookValue = IntPtr.Zero;         const int WM_CLICK = 0x00F5;         public Form1()         {

The_Eyes的博客 918

C# 键盘钩子

/// <summary> /// 安装键盘钩子 /// </summary> public void Hook_Start() { if (hHook == 0) { KeyBoardHookProcedure...

weixin_30426065的博客 165

C#实现屏幕键盘(软键盘 ScreenKeyboard)

要实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子,也就是系统范围的钩子。什么是钩子(Hook)    钩子(Hook)是Windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先    启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通    过系统调用,把它挂入系统。每当特定的消息发出,

Mark的专栏 3208
上一篇: Excel插件快捷键弹窗事件(VSTO+键盘钩子实现)
下一篇: VS2013安装失败——系统找不到指定路径以及如何彻底卸载vs2013
PGEva
博客等级 码龄10年 78粉丝 129原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值