本文采用两个案例说明键盘钩子的使用,案例一是使用线程钩子,案例2是系统钩子(实现跨程序获取键值)

案例一:线程钩子

该例子实现的效果是:拦截键盘的输入,如果输入的是B键或者是b键,就弹出消息框来表示一下拦截到了

步骤:

1 新建Winform应用程序,工程命名为HookDemo,把默认生成的窗体名称改为HookTest

2 新建一个类,名为Hook

编写代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;  //引入的命名空间
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;            //引入的命名空间namespace HookDemo
{internal enum HookType { Keyboard=2   //键盘钩子类型}//定义委托,该委托的参数是固定这样写internal delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);public class Hook{//记录下一个Hook编号static IntPtr _nextHookPtr;//获取当前线程编号[DllImport("kernel32.dll")]static extern int GetCurrentThreadId();//卸载钩子[DllImport("User32.dll")]internal extern static void UnhookWindowsHookEx(IntPtr handle);//安装钩子[DllImport("User32.dll")]internal extern static IntPtr SetWindowsHookEx(int idHook,[MarshalAs(UnmanagedType.FunctionPtr)]HookProc Ipfn,IntPtr hanstance,int threadID);//获取下一个钩子[DllImport("User32.dll")]internal extern static IntPtr CallNextHookEx(IntPtr handle,int code,IntPtr wparam,IntPtr Iparam);//委托回调的方法IntPtr MyHookProc(int code,IntPtr wparam,IntPtr Iparam) {if (code < 0){//让后面的程序处理该消息return CallNextHookEx(_nextHookPtr, code, wparam, Iparam);}//用户输入的是b或者Bif (wparam.ToInt32() == 98 || wparam.ToInt32() == 66){//设置文本输入框为aMessageBox.Show("我拦截到B或者b");//该消息结束return (IntPtr)1;}else{//让后面的程序处理该消息return IntPtr.Zero;}}/// <summary>/// 从外部调用设置钩子/// </summary>public void SetHook() {//已经设置过钩子了,不能重复设置if(_nextHookPtr!=IntPtr.Zero){return;}//设置钩子委托回调函数(委托方法注册)HookProc myhookProc = new HookProc(MyHookProc);//把该钩子加到Hook链中_nextHookPtr = SetWindowsHookEx((int)HookType.Keyboard,myhookProc,IntPtr.Zero,GetCurrentThreadId());}/// <summary>/// 从外部调用卸载钩子/// </summary>public void UnHook() { if(_nextHookPtr!=IntPtr.Zero){//从Hook链中取消UnhookWindowsHookEx(_nextHookPtr);}_nextHookPtr = IntPtr.Zero;}}
}

3 找到默认生成的窗体,并找到该窗体的FormClosing事件函数,如下图:

4  编写默认窗体下的类HookTest如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace HookDemo
{public partial class HookTest : Form{Hook hook = new Hook();public HookTest(){InitializeComponent();//设置钩子hook.SetHook();}//页面关闭事件函数private void HookTest_FormClosing(object sender, FormClosingEventArgs e){//卸载钩子hook.UnHook();}}
}

5 运行程序,并按键盘的B键,输出如下图:

案例二:系统钩子

先看一下例子的效果:

拓展:如果把黑窗体隐藏,然后设置为自启动,同时定时判断浏览器输入的url是否为某个url,如果是则进行抓取然后写到自己的数据库,你说能干什么坏事,呵呵,当然这只是想想而已

步骤如下:

1 新建Winform应用程序,工程命名为跨程序拦截输入的字符串

2 新建一个类,名为SystemHook

代码如下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;namespace 跨程序拦截输入的字符串
{class SystemHook{// 设置钩子[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern IntPtr SetWindowsHookEx(int idHook, HookHandlerDelegate lpfn, IntPtr hmod, uint dwThreadID);// 卸载钩子 [DllImport("user32.dll")]public static extern bool UnhookWindowsHookEx(IntPtr idHook);// 获取模块句柄[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern IntPtr GetModuleHandle(String modulename);public const int WM_KEYDOWN = 0x0100;public const int WH_KEYBOARD_LL = 13;public const int WM_SYSKEYDOWN = 0x0104;public struct KBDLLHOOKSTRUCT{public int vkCode;public int scanCode;public int flags;public int time;public int dwExtraInfo;}public delegate int HookHandlerDelegate(int nCode, IntPtr wparam, ref KBDLLHOOKSTRUCT lparam);//钩子回掉委托实例private static HookHandlerDelegate proc;//钩子句柄private static IntPtr hKeyboardHook;private static int HookCallback(int nCode, IntPtr wparam, ref KBDLLHOOKSTRUCT lparam){if (nCode >= 0&&(wparam == (IntPtr)WM_KEYDOWN||wparam == (IntPtr)WM_SYSKEYDOWN)){//Console.WriteLine(lparam.vkCode);if (lparam.vkCode == 13){Console.WriteLine("按下回车键");return 0;}else if (lparam.vkCode == 8){Console.WriteLine("按下backspace键");return 0;}else if (lparam.vkCode == 20){Console.WriteLine("按下大小写切换键");return 0;}else if (lparam.vkCode ==160||lparam.vkCode==161){Console.WriteLine("按下shift键");return 0;}else if (lparam.vkCode == 162){Console.WriteLine("按下ctrl键");return 0;}else if (lparam.vkCode == 190){Console.Write(".");return 0;}byte[] array = new byte[1];array[0] = (byte)(Convert.ToInt32(lparam.vkCode)); //ASCII码强制转换二进制Console.Write(Convert.ToString(System.Text.Encoding.UTF8.GetString(array)).ToLower());}return 0;}public static void HookStart(){if (hKeyboardHook == IntPtr.Zero){// 创建HookProc实例 proc = new HookHandlerDelegate(HookCallback);using (Process curPro = Process.GetCurrentProcess())using (ProcessModule curMod = curPro.MainModule){//定义全局钩子 hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curMod.FileName), 0);}if (hKeyboardHook == IntPtr.Zero){HookStop();throw new Exception("钩子设置失败");}}}public static void HookStop(){bool retKeyboard = true;if (hKeyboardHook != IntPtr.Zero){retKeyboard = UnhookWindowsHookEx(hKeyboardHook);hKeyboardHook = IntPtr.Zero;}if (!(retKeyboard)) throw new Exception("卸载钩子失败");}}
}

3  调用使用,在默认的窗台Form1中输入代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 跨程序拦截输入的字符串
{public partial class Form1 : Form{public Form1(){InitializeComponent();this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);SystemHook.HookStart();}private void Form1_FormClosing(object sender, FormClosingEventArgs e){SystemHook.HookStop();}}
}

运行即可得到前面所展示的效果图

钩子函数(键盘钩子C#)相关推荐

  1. vs2019键盘钩子_键盘钩子WH_KEYBOARD和WH_KEYBOARD_LL

    WH_KEYBOARD和WH_KEYBOARD_LL,这两个都是键盘钩子 区别: 1.MSDN上面说的是WH_KEYBOARD会在应用程序调用GetMessage 或者 PeekMessage函数并且 ...

  2. mysql 钩子函数_Flask钩子函数是什么

    Flask钩子函数 在Flask中钩子函数是使用特定的装饰器的函数.为什么叫做钩子函数呢,是因为钩子函数可以在正常执行的代码中,插入一段自己想要执行的代码,那么这种函数就叫做钩子函数. before_ ...

  3. Vue钩子函数之钩子事件hookEvent,监听组件

    在Vue当中,hooks可以作为一种event,在Vue的源码当中,称之为hookEvent. 在Vue组件中,可以用过$on,$once去监听所有的生命周期钩子函数,如监听组件的updated钩子函 ...

  4. java中钩子函数回调函数_钩子函数和回调函数

    一般认为,钩子函数就是回调函数的一种,其实还是有差异的,差异地方就是:触发的时机不同. 先说钩子函数: 钩子(Hook)概念源于Windows的消息处理机制,通过设置钩子,应用程序对所有消息事件进行拦 ...

  5. 键盘钩子实现扫码枪输入

    钩子 钩子是操作系统消息处理的一种机制.通过钩子,应用程序可以安装一个钩子回调过程让系统调用,从而监视系统中的消息队列.在这些消息到达目标窗口之前对这些消息进行处理. 特点 钩子函数会降低操作系统的性 ...

  6. pytest合集(10)— Hook钩子函数

    一.钩子函数 钩子函数这个称呼是很多开发语言中都会涉及到的一个东西. 1.理解钩子函数 如何理解钩子函数 - 知乎 2.pytest的钩子函数 Hooks钩子函数是pytest框架预留的函数,通过这些 ...

  7. 初探 Vue 生命周期和钩子函数

    生命周期 生命周期函数就是 Vue 实例在某一个时间点会自动执行的函数. 简单来说就是好像把人的出生到死亡分成一个个阶段,你取名字肯定是在你出生阶段,而不是在成年阶段:你结婚肯定是在成年阶段,而不是在 ...

  8. 钩子函数和回调函数的区别

    一般认为,钩子函数就是回调函数的一种,其实还是有差异的,差异地方就是:触发的时机不同. 先说钩子函数: 钩子(Hook)概念源于Windows的消息处理机制,通过设置钩子,应用程序对所有消息事件进行拦 ...

  9. django12:form 组件/渲染标签/数据校验/钩子函数/

    基本用法 from django import forms# 自己写一个类 class RegForm(forms.Form):username= forms.CharField(min_length ...

最新文章

  1. Python Qt GUI设计:QSpinBox计数器类(基础篇—15)
  2. 前端异步请求数据未获取导致报错解决办法
  3. 机器学习算法加强——回归
  4. Halcon资料:image,region,xld三者如何转化和保存
  5. php7 参数类型限定,PHP参数类型限制 - Corwien的博客 - OSCHINA - 中文开源技术交流社区...
  6. android gradle错误,Android studio gradle错误与顶级异常
  7. android 仿美团悬浮,类似美团悬浮框的效果
  8. 微信号也有加人涨粉规则和限制?
  9. 需求定律的3大挑战——《可以量化的经济学》
  10. Java开发学习教程之对象的创建与使用
  11. HDU 1195 Open the Lock BFS
  12. java实现ping_java实现Ping示例代码
  13. iOS开发月报#3|201809
  14. 02_爬取灌篮高手全国大赛漫画
  15. tensorflow学习笔记——获取训练数据集和测试数据集
  16. 呵护流量尖峰时刻,我们是互联网的“守夜人”
  17. php+js扫码枪实现签到的功能
  18. 尚硅谷-微信小程序文档
  19. vue中集成的ui组件库_Vue组件可使用Vault Flow通过Braintree集成PayPal付款
  20. 计算机英语wheel是什么意思,wheel是什么意思

热门文章

  1. sequence library
  2. Android常用图片加载库介绍及对比
  3. 仿酷狗音乐播放器开发日志十五——音乐电台列表控件的实现
  4. 三分钟教你Word修改默认样式
  5. Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)
  6. 海康、大华等网络摄像头RTSP_Onvif网页无插件直播流媒体服务器EasyNVR之加密机使用方法详解
  7. 甘肃临洮玉琢冰雕造“梦幻仙境”
  8. 不小心删除的文件怎么找回?
  9. java使用ByteBuffer.allocateDirect分配的堆外内存大小查看方法
  10. 12月11日第壹简报,星期日,农历十一月十八