1.实现钩子函数

钩子(Hook)的实现需要三个主要的函数和一个委托

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr
hInstance, int threadId);//设置系统钩子

[DllImport("user32.dll",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);//卸载系统钩子

[DllImport("user32.dll",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam,
IntPtr lParam);//调用下一个钩子函数

public
delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);//用于处理Hook住的消息

当我们在执行一个操作的时候,首先不是由我们的窗体获得消息,而是系统获得,然后系统再把消息发送到对应的窗体,Hook就是在窗体获取到信息之前抓住信息,然后对信息进行处理,然后可以传递给船体继续执行,或者就不传递给窗体

当在HookProc处理消息的时候,如果return 1,那么消息就会被截断,不会再传递到目标窗口,如果return的是CallNextHookEx那么就会继续调用下一个钩子,如果下面没有钩子了,那么消息就会被传递到目标窗体进行处理

SetWindowsHookEx第一个参数是需要勾住的消息类型,总共14种消息类型,如下

public
const int WH_JOURNALRECORD = 0;
public const int constWH_JOURNALPLAYBACK = 1;
public const int WH_KEYBOARD = 2;
public const int WH_GETMESSAGE = 3;
public const int WH_CALLWNDPROC = 4;
public const int WH_CBT = 5;
public const int WH_SYSMSGFILTER = 6;
public const int WH_MOUSE = 7;
public const int WH_HARDWARE = 8;
public const int WH_DEBUG = 9;
public const int WH_SHELL = 10;
public const int WH_FOREGROUNDIDLE = 11;
public const int WH_CALLWNDPROCRET = 12;
public const int WH_KEYBOARD_LL = 13;
public const int WH_MOUSE_LL = 14;

第二个参数就是HookProc委托,用于对钩住的消息进行处理,

第三个参数是需要钩住的实例的句柄,最后一个是钩住的线程,如果是0则是全局钩住

返回值为抓住的钩子的ID

UnhookWindowsHookEx卸载掉钩子,参数为上面返回的ID

辅助函数

[DllImport("kernel32.dll")]

public static extern IntPtr
GetModuleHandle(string name);//根据模块名称获取到对应的句柄

[DllImport("user32.dll",
EntryPoint = "FindWindow")]

private extern static IntPtr
FindWindow(string lpClassName, string lpWindowName);//查询一个窗体

[DllImport("User32.dll",
EntryPoint = "FindWindowEx")]

private static extern IntPtr
FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string
lpClassName, string lpWindowName);//获取窗体中的所有子窗体(文本框,按钮等,都属于窗体)

[DllImport("user32.dll")]

public static extern int EnumChildWindows(IntPtr
hWndParent, CallBack lpfn, int lParam);//枚举窗体中的所有子窗体

public delegate bool CallBack(IntPtr hwnd, int
lParam);

此委托是EnumChildWindows的回调函数,用于遍历的时候对窗口进行处理

根据Module的名字获取到对应的句柄SetWindowsHookEx的第三个参数可以使用这个函数来获得。

下面是一个示例程序,设置一个全局钩子,作用是,如果输入的字符是小写字母,则直接转换为大写字母。

1.1  HookProc的方法实现

private int
MessageHandle(int nCode, Int32 wParam, IntPtr
lParam)

{

if (0x100 == wParam || 0x101 ==
wParam)  //如果按键为按下状态,如果没有这句判断,则内部代码会执行两遍,一遍是KeyDown一遍是KeyUp

{

KBDLLHOOKSTRUCT ks = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam,
typeof(KBDLLHOOKSTRUCT));

//将所有的小写字母直接加1

if (ks.vkCode >= 65 &&
ks.vkCode <= 90)

{

string
cUpper = Convert.ToChar(ks.vkCode).ToString().ToUpper();

SendMessage(txtHandle,
0x0c, IntPtr.Zero, cUpper);

}

}

return CallNextHookEx(result, nCode, 0,
lParam);

}

1.2 KBDLLHOOKSTRUCT结构体(这个结构体因为不同的钩子内容会不一样)

public struct KBDLLHOOKSTRUCT

{

public int vkCode;

public int scanCode;

public int flags;

public int time;

public IntPtr
dwExtraInfo;

}

1.3设置钩子和卸载钩子(两个按钮的事件)

private void btnInstallHook_Click(object
sender, EventArgs e)

{

HookProc
hProc = new HookProc(MessageHandle);

IntPtr
cInstance = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);

result = SetWindowsHookEx(HookHelper.WH_KEYBOARD_LL, hProc, cInstance, 0);

}

private
void btnUnhook_Click(object
sender, EventArgs e)

{

UnhookWindowsHookEx(result);

}

辅助方法:为了获取到窗体中的文本框的句柄

//枚举窗体中的子窗体的回调函数

private
bool EnumWindow(IntPtr
hwnd, int lParam)

{

StringBuilder
sb=new StringBuilder();

GetWindowText(hwnd, sb, 10);

if
(sb.ToString() == "HookTest")

{

txtHandle = hwnd;

}

return
true;

}

2.SendMessage的使用

可以使用SendMessage模拟给发送一条系统消息

[DllImport("user32.dll",
EntryPoint = "SendMessage")]

private
static extern int SendMessage(IntPtr
hwnd, int wMsg, IntPtr
wParam, IntPtr lParam);

[DllImport("User32.dll", EntryPoint = "SendMessage")]

private
static extern int SendMessage(IntPtr
hWnd, int Msg, IntPtr
wParam, string lParam);//发送消息,此重载方法可以直接给文本框赋值

下面是一个自动点击按钮和自动给文本框赋值的示例

private void btnTest_Click(object
sender, EventArgs e)

{

#region 自动点击按钮

//IntPtr
cProcess = FindWindow(null, "测试Hook");

//winHandle
= FindWindowEx(cProcess, IntPtr.Zero, null, "点击显示界面");

////SendMessage(winHandle,
0xf5, 0, 0);//0xf5 BM_CLICK 按钮单击对应的消息--经过测试,直接使用0xf5无法实现点击按钮的功能

////测试结果发现,如果想要实现单击按钮的功能,必须先按下鼠标左键,再抬起鼠标左键

//SendMessage(winHandle,
0x201, IntPtr.Zero, IntPtr.Zero);//0x201 WM_LBUTTONDOWN 按下鼠标左键对应的消息

//SendMessage(winHandle,
0x202, IntPtr.Zero, IntPtr.Zero);//0x201 WM_LBUTTONUP 抬起鼠标左键对应的消息

#endregion

#region 自动输入文本

//IntPtr
cProcess = FindWindow(null, "Test.txt - 记事本");

//winHandle
= FindWindowEx(cProcess, IntPtr.Zero, null, "");

//IntPtr
cProcess = FindWindow(null, "测试Hook");

//winHandle
= FindWindowEx(cProcess, IntPtr.Zero, null, null);

////winHandle
= new IntPtr(0xE10F2);//这种方式是先通过Spy++找到控件的句柄,然后再使用这个句柄进行数据交互(此方法每次重启窗体,对应的句柄都会发生变化)

//SendMessage(txtHandle,
0x0c, IntPtr.Zero, "ABCDEFGHIJKLMN");//0x0c wm_settext 给窗体设置文本

#endregion

}

源代码:https://files.cnblogs.com/files/ckym/HookTest.rar

Net实现钩子函数(Hook)以及通过SendMessage实现自动点击按钮和给文本框赋值的更多相关文章

  1. Cypress系列(9)- Cypress 编写和组织测试用例篇 之 钩子函数Hook

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html Hook 就是常说的钩子函数,在 pyt ...

  2. Flask初学者:g对象,hook钩子函数

    Flask的g对象 作用:g可以可以看作是单词global的缩写,使用“from flask import g”导入,g对象的作用是保存一些在一次请求中多个地方的都需要用到的数据,这些数据可能在用到的 ...

  3. 让你轻松掌握 Python 中的 Hook 钩子函数

    1. 什么是Hook 经常会听到钩子函数(hook function)这个概念,最近在看目标检测开源框架mmdetection,里面也出现大量Hook的编程方式,那到底什么是hook?hook的作用是 ...

  4. Netfilter 之 钩子函数注册

    通过注册流程代码的分析,能够明确钩子函数的注册流程,理解存储钩子函数的数据结构,如下图(点击图片可查看原图): 废话不多说,开始分析: nf_hook_ops是注册的钩子函数的核心结构,字段含义如下所 ...

  5. Forms组件与钩子函数

    目录 一:Forms组件 1.案例需求: 2.前端 3.后端 二:form表单前后端动态交互 1.form组件 2.为什么数据效验非要去后端 不能在前端利用js直接完成呢? 3.举例:购物网站 三:基 ...

  6. Vue.js 第2章 钩子函数&自定义指令&过滤器&计算属性&侦听器

    目标 钩子函数 自定义指令 自定义过滤器 计算属性 监听属性 局部自定义指令 为什么需要自定义指令 为了复用,为了代码的灵活 指令的分类:全局指令,局部指令 在vm外面创建的指令 通过Vue.dire ...

  7. HOOK钩子 - 钩子函数说明

    翻译参考自MaybeHelios的blog: http://blog.csdn.net/maybehelios/ 通过SetWindowsHookEx方法安装钩子,该函数指定处理拦截消息的钩子函数(回 ...

  8. GET/POST/g和钩子函数(hook)

    GET请求和POST请求: 1. get请求: * 使用场景:如果只对服务器获取数据,并没有对服务器产生任何影响,那么这时候使用get请求. * 传参:get请求传参是放在url中,并且是通过`?`的 ...

  9. Hive Query生命周期 —— 钩子(Hook)函数篇

    无论你通过哪种方式连接Hive(如Hive Cli.HiveServer2),一个HQL语句都要经过Driver的解析和执行,主要涉及HQL解析.编译.优化器处理.执行器执行四个方面. 以Hive目前 ...

随机推荐

  1. 关于window.getSelection

    window.getSelection(),返回一个Selection对象,表示用户选择的文本范围或光标的当前位置. selection对象先来看下面两个selection结果:selection对象 ...

  2. adb 常用命令一

    1.install 和uninstall adb -s 设备号 install 安装包路径   adb uninstall package名 2.pull 和push: adb pull /sdcar ...

  3. Redis Streams 介绍

    Stream是Redis 5.0版本引入的一个新的数据类型,它以更抽象的方式模拟日志数据结构,但日志仍然是完整的:就像一个日志文件,通常实现为以只附加模式打开的文件,Redis流主要是一个仅附加数据结 ...

  4. CT窗宽位宽

    先说一下CT值是什么 CT图像反映的是人体对X射线吸收的系数,但我们关心的是各组织结构的密度差异,即相对密度,如果某组织发生病变,其密度就会发生变化,但由于比较吸收系数非常繁琐,于是亨氏把组织器官对X ...

  5. phpstudy 首次安装后打开网站 数据库内容 中文乱码

    首次安装完成 phpstudy 后,默认的 my.ini 配置只有数据库文件位置,其他的都没有设置,这时如果想要输出数据库中的中文后,显示到页面上就会变成中文乱码 解决方法: 打开 phpstudy ...

  6. 开源插件 :MahApps.Metro.IconPacks

    详见英文版:https://github.com/MahApps/MahApps.Metro.IconPacks/wiki 源代码名称:MahApps.Metro.IconPacks 源代码网址:ht ...

  7. Scrapy之Spider

    Spider Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取的动作及 ...

  8. 爬虫中采集动态HTML介绍

    JavaScript JavaScript 是网络上最常用也是支持者最多的客户端脚本语言.它可以收集 用户的跟踪数据,不需要重载页面直接提交表单,在页面嵌入多媒体文件,甚至运行网页游戏. 我们可以在网 ...

  9. Oracle系列十四 序列、索引和同义词

    序列 : 提供有规律的数值.索引  : 提高查询的效率同义词  :给对象起别名 序列: 可供多个用户用来产生唯一数值的数据库对象 自动提供唯一的数值 共享对象 主要用于提供主键值 将序列值装入内存可以 ...

  10. Maven依赖包导入错误(IntelliJ IDEA):java.lang.OutOfMemoryError: GC overhead limit exceeded

    一.问题背景 最近用IntelliJ IDEA 打开一个老应用,一直加载依赖不成功,主POM中存在如下错误. java.lang.OutOfMemoryError:GC overhead limit ...