当前位置: 首页 > 编程日记 > 正文

用C#钩子写一个改键外挂

我的微信群——软件开发测试工程师交流群,欢迎扫码:

改键是一种习惯,比如在玩儿lol或者dota的时候。理论上玩儿什么游戏都可以改键。

做一个窗体(点击Install——应用改键,点击Uninstall——撤销应用):

窗体定义代码如下:

using System.Windows.Forms;namespace KeysExchange
{partial class Form1{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){this.intall_button = new System.Windows.Forms.Button();this.uninstall_button = new System.Windows.Forms.Button();this.comboBox1 = new System.Windows.Forms.ComboBox();this.comboBox2 = new System.Windows.Forms.ComboBox();this.label1 = new System.Windows.Forms.Label();this.SuspendLayout();// // intall_button// this.intall_button.Location = new System.Drawing.Point(179, 162);this.intall_button.Name = "intall_button";this.intall_button.Size = new System.Drawing.Size(75, 23);this.intall_button.TabIndex = 4;this.intall_button.Text = "Install";this.intall_button.UseVisualStyleBackColor = true;this.intall_button.Click += new System.EventHandler(this.intall_button_Click);// // uninstall_button// this.uninstall_button.Location = new System.Drawing.Point(179, 207);this.uninstall_button.Name = "uninstall_button";this.uninstall_button.Size = new System.Drawing.Size(75, 23);this.uninstall_button.TabIndex = 5;this.uninstall_button.Text = "Uninstall";this.uninstall_button.UseVisualStyleBackColor = true;this.uninstall_button.Click += new System.EventHandler(this.uninstall_button_Click);// // comboBox1// this.comboBox1.FormattingEnabled = true;this.comboBox1.Location = new System.Drawing.Point(54, 41);this.comboBox1.Name = "comboBox1";this.comboBox1.Size = new System.Drawing.Size(57, 21);this.comboBox1.TabIndex = 6;this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;// // comboBox2// this.comboBox2.FormattingEnabled = true;this.comboBox2.Location = new System.Drawing.Point(175, 41);this.comboBox2.Name = "comboBox2";this.comboBox2.Size = new System.Drawing.Size(57, 21);this.comboBox2.TabIndex = 7;this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;// // label1// this.label1.AutoSize = true;this.label1.Location = new System.Drawing.Point(126, 44);this.label1.Name = "label1";this.label1.Size = new System.Drawing.Size(43, 13);this.label1.TabIndex = 8;this.label1.Text = "改为:";// // Form1// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(301, 273);this.Controls.Add(this.label1);this.Controls.Add(this.comboBox2);this.Controls.Add(this.comboBox1);this.Controls.Add(this.uninstall_button);this.Controls.Add(this.intall_button);this.Name = "Form1";this.Text = "KeysExchange";this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.Button intall_button;private System.Windows.Forms.Button uninstall_button;private System.Windows.Forms.ComboBox comboBox1;private System.Windows.Forms.ComboBox comboBox2;private System.Windows.Forms.Label label1;}struct ComboItem{private string text;private string value;public ComboItem(string text, string value){this.text = text;this.value = value;}public override string ToString(){return this.text;}public string ToValue(){return this.value;}}
}

钩子代码如下:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;namespace KeysExchange
{public class KeyboardHookLib{private const int WH_KEYBOARD_LL = 13;      private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);public delegate void ProcessKeyHandle(HookStruct param, out bool handle);private static int _hHookValue = 0;private HookHandle _KeyBoardHookProcedure;[StructLayout(LayoutKind.Sequential)]public class HookStruct{public int vkCode;public int scanCode;public int flags;public int time;public int dwExtraInfo;}[DllImport("user32.dll")]private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]private static extern bool UnhookWindowsHookEx(int idHook);[DllImport("user32.dll")]private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);[DllImport("kernel32.dll")]private static extern int GetCurrentThreadId();[DllImport("kernel32.dll")]private static extern IntPtr GetModuleHandle(string name);private IntPtr _hookWindowPtr = IntPtr.Zero;public KeyboardHookLib() { }private static ProcessKeyHandle _clientMethod = null;[DllImport("user32")]public static extern int GetKeyboardState(byte[] pbKeyState);[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]private static extern short GetKeyState(int vKey);private const int WM_KEYDOWN = 0x100;//KEYDOWNprivate const int WM_KEYUP = 0x101;//KEYUPprivate const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWNprivate const int WM_SYSKEYUP = 0x105;//SYSKEYUPpublic void InstallHook(ProcessKeyHandle clientMethod){_clientMethod = clientMethod;if (_hHookValue == 0){_KeyBoardHookProcedure = new HookHandle(OnHookProc);_hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);_hHookValue = SetWindowsHookEx(WH_KEYBOARD_LL, _KeyBoardHookProcedure, _hookWindowPtr, 0);if (_hHookValue == 0) UninstallHook();}}public void UninstallHook(){if (_hHookValue != 0){if (UnhookWindowsHookEx(_hHookValue)){_hHookValue = 0;}}}private static int OnHookProc(int nCode, int wParam, IntPtr lParam){if (nCode >= 0){HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));if (_clientMethod != null){bool handle = false;///Tylan: Judge if the event is KeyDown or not.if (lParam.ToInt32() > 0 && wParam == 0x100){_clientMethod(hookStruct, out handle);}if (handle) return 1; }}return CallNextHookEx(_hHookValue, nCode, wParam, lParam);}}
}

逻辑部分代码如下:

using System;
using System.Windows.Forms;namespace KeysExchange
{public partial class Form1 : Form{private KeyboardHookLib _keyboardHook = null;public Form1(){InitializeComponent();for (int alp = 65; alp <= 90; alp++){ComboItem item = new ComboItem(((Keys)alp).ToString(), alp.ToString());comboBox1.Items.Add(item);comboBox2.Items.Add(item);}}private void intall_button_Click(object sender, EventArgs e){//Install the hook._keyboardHook = new KeyboardHookLib();_keyboardHook.InstallHook(this.OnKeyPress);}private void uninstall_button_Click(object sender, EventArgs e){//Cancel the hook.if (_keyboardHook != null) _keyboardHook.UninstallHook();}public void OnKeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle){handle = false;if (((Keys)hookStruct.vkCode).ToString() == comboBox1.SelectedItem.ToString()) {handle = true;//Exchange the keys.hookStruct.vkCode = int.Parse(((ComboItem)comboBox2.SelectedItem).ToValue());Keys key = (Keys)hookStruct.vkCode;//MessageBox.Show((key == Keys.None ? "" : key.ToString()));
                System.Windows.Forms.SendKeys.Send(key.ToString().ToLower());}}}
}

F5运行,找个游戏试一下,改键成功啦(按p成功打开背包)~

转载于:https://www.cnblogs.com/LanTianYou/p/5053682.html

相关文章:

Spring中WebApplicationContext

ApplicationContext是Spring的核心&#xff0c;Context我们通常解释为上下文环境&#xff0c;我想用“容器”来表述它更容易理解一 些&#xff0c;ApplicationContext则是“应用的容器”了:P&#xff0c;Spring把Bean放在这个容器中&#xff0c;在需要的时候&#xff0c;用getB…

洛谷 P1966 火柴排队

题意 给定2个等长序列a、b&#xff0c;要求通过交换使 \[\sum_{i1}^{n}(a_i-b_i)^2\] 最小。 分析 看着这个式子&#xff0c;我突然想到了方差。很明显&#xff0c;方差反应数据的波动程度&#xff0c;所以让数据集中就可以使方差变小了。而对应到这个公式&#xff0c;大方向就…

Revit结构2021-2022从零到精通

流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |大小解压后:8.6 GB 含课程文件 |时长:14h 46m 涵盖Revit结构2021-2022的基本、中级和高级功能 Revit Str…

BZOJ1922: [Sdoi2010]大陆争霸

题目&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id1922 带限制最短路。 每个点真正的dis是max(dis[i],dis[v]),v是其保护点。 可以把题目中的保护转化为每个点的贡献。 每次扫一边连出的边做最短路把rd为0的点加入队列。 再扫一遍自己的贡献&#xff0c;更新它…

Java学习总结:43(转换流)

转换流 字节流和字符流的转换可以通过InputStreamReader、OutputStreamWriter两个类转换&#xff0c;下面是这两个类的继承结构和构造方法 名称定义构造构造方法InputStreamReaderpublic class InputStreamReader extends Readerpublic InputStreamReader(InputStream in)Out…

2022-2028年中国环保服务业投资分析及前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国环保服务行业市场行业相关概述、中国环保服务行业市场行业运行环境、分析了中国环保服务行…

一个build.xml实例

<?xml version"1.0"?> <project name"ssh" basedir"." default"usage"> <property name"name" value"ssh"/> <property name"war.dir" value"war"/> &l…

Spring Boot 2.0 常见问题总结(一)

SpringBoot2.x 依赖环境和版本新特性说明 依赖版本 jdk8 以上, Springboot2.x 用 JDK8 , 因为底层是 Spring framework5 。jar 包方式运行 SpringBoot 项目时问题 打包成jar包&#xff0c;需要增加maven依赖。 <build><plugins><plugin><groupId>org.s…

UE4场景设计学习教程

视频:MPEG4视频(H264) 19201080 25fps 1400kbps |音频:AAC 44100Hz立体声128kbps 语言&#xff1a;西班牙语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:35节课(6小时36分钟) 文件大小:4.7 GB 学会使用这个强大的软件的工具&#xff0c;一步一步地创造…

Java学习总结:44(文件复制案例)

案例&#xff1a;文件复制(针对InputStream和OutputStream的操作应用) 流程图(比较复杂我就不敲了&#xff0c;直接拍出来) 例&#xff1a;实现文件复制操作 package Project.Study.FileCopyCase;import java.io.*;public class Test {public static void main(String[]args…

java多态的理解

Java中多态性的实现 什么是多态 面向对象的三大特性&#xff1a;封装、继承、多态。从一定角度来看&#xff0c;封装和继承几乎都是为多态而准备的。这是我们最后一个概念&#xff0c;也是最重要的知识点。多态的定义&#xff1a;指允许不同类的对象对同一消息做出响应。即同一…

2022-2028年中国高密度聚乙烯(HDPE)行业市场发展调研及投资前景分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国高密度聚乙烯(HDPE)行业市场行业相关概述、中国高密度聚乙烯(HDPE)行业市场行业运行环境、…

计算机视觉图像处理机器学习压缩感知等论文代码大全

点击链接进入相关博文 1.来自西弗吉利亚大学li xin整理的CV代码合集 主要包括&#xff1a; 1.图像去噪&#xff0c;编码&#xff0c;去马赛克&#xff0c;超分辨&#xff0c;分割&#xff0c;去模糊&#xff0c;纹理合成&#xff0c;修复&#xff0c;质量评估等 2.视频编码和目…

Java 17 VS Java 8: 新旧对决,这些Java 17新特性你不容错过

Java是一门非常流行的编程语言,由于其跨平台性、可移植性以及强大的面向对象特性而备受青睐。Java最初由Sun Microsystems公司于1995年推出,随着时间的推移,Java发展迅速,版本不断更新。本篇博客将重点介绍Java 17与Java 8的对比,以及Java 17的新特性。

VirtualBox装ghost XP

在win7 professional 64上安装了virtualBox4.3.14 r95030 版本&#xff0c;之所以要安装这个vb,是因为刚升级的vm 打开之后很占用cpu&#xff0c; 网上又说vb不是很占用cpu而且是开源的&#xff0c; 于是就安装来试试&#xff0c; 但是以前没玩过&#xff0c; 哪知道安装个xp都…

【Java】常用的函数式接口(含示例)

Supplier接口被称为生产型接口:指定泛型是什么类型,接口的get()方法就会生产什么样的类型的数据。具体怎样消费、怎样使用这个数据呢?就由之后传入的Lambda表达式决定吧!与生产工厂Supplier相反,Consumer用来消费,即使用一个数据。具体生成一个怎样的数据?就由之后传入的Lambda表达式决定吧!转换的过程是怎样的呢?就由之后传入的Lambda表达式决定吧!具体根据什么判断呢?就由之后传入的Lambda表达式决定吧!对某种数据类型的数据进行判断,返回一个布尔值。

写实的CG人物角色制作学习教程

艺术站-制作欧比旺克诺比逼真的Cg角色 大小解压后&#xff1a;4.98G 含课程素材文件 1920X1080 .mp4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 信息: 欧比旺是我一直以来最喜欢的角色之一&#xff0c;所以有时间做这个3D人像真的很好…

Java学习总结:45(字符编码)

字符编码 在实际工作中最常见的4种编码如下&#xff1a; GBK、GB2312&#xff1a;中文的国标编码&#xff0c;其中GBK包含简体中文与繁体中文两种&#xff0c;而GB2312只包含简体中文&#xff1b; ISO8859-1&#xff1a;是国际编码&#xff0c;可以描述任何文字信息(中文需要转…

js实现双击后网页自己主动跑-------Day55

公司的界面设计环节总算是告一段落了&#xff0c;必需要承认的是&#xff0c;这段时间晚间的学习带给我非常多益处。在工作中偶尔的应用&#xff0c;效果出奇的好&#xff0c;收到领导和同事的一些小赞扬&#xff0c;表示非常欣慰&#xff0c;也长了点不少自信&#xff0c;尽管…

2022-2028年中国高等职业教育产业投资分析及前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国高等职业教育行业市场行业相关概述、中国高等职业教育行业市场行业运行环境、分析了中国高…

「轻松支付,只需几步」使用 LeanCloud 云代码接入支付宝示例

如果你的应用想接入支付宝&#xff0c;让用户可以在应用内部直接支付&#xff0c;你可以看下这篇文档和开源项目&#xff0c;也许会给你带来一些帮助。 项目&#xff1a;https://github.com/leancloud/cloud-code-alipay 了解支付宝「即时到账收款」 在尝试该项目之前&#xff…

quartz定时任务开发cron常用网站

http://cron.qqe2.com/ cron表达式 只能看下5个时点http://www.cronmaker.com/ 能看500个时点https://unixtime.51240.com/unix时间戳 quartz定时任务开发常常需要用到一些工具。 如cron表达式的构造&#xff0c;绝对时间&#xff0c;时间戳的定位&#xff0c;单调的时候要看…

UE5使用MetaHuman构建超现实的角色

使用免费的MetaHuman创造者应用程序为虚幻构建超现实的角色。 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;48.0 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大小解压后:1.66 GB 含课程文件|时长:1h 49…

Java学习总结:46(内存流)

内存流 在Java中&#xff0c;针对内存操作提供了以下两组类&#xff1a; 字节内存流&#xff1a;ByteArrayInputStream(内存字节输入流)、ByteArrayOutputStream(内存字节输出流)&#xff1b;字符内存流&#xff1a;CharArrayReader(内存字符输入流)、CharArrayWriter(内存字…

数据结构之shell排序

希尔排序是插入排序的一种类型&#xff0c;也可以用一个形象的叫法缩小增量法。基本思想就是把一个数组分为好几个数组&#xff0c;有点像分治法&#xff0c;不过这里的划分是用一个常量d来控制。 这个0<d<n,n为数组的长度。这个算法有了插入排序的速度&#xff0c;也可以…

2022-2028年中国高纯铜市场研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国高纯铜行业市场行业相关概述、中国高纯铜行业市场行业运行环境、分析了中国高纯铜行业市场…

【百度地图API】如何制作班级地理通讯录?LBS通讯录

原文:【百度地图API】如何制作班级地理通讯录&#xff1f;LBS通讯录摘要&#xff1a;班级通讯录必备的功能&#xff0c;比如人员列表&#xff0c;人员地理位置标注&#xff0c;展示复杂信息窗口&#xff0c;公交和驾车等。一般班级人员都不会超过300个&#xff0c;因为可以高效…

Windows Azure Virtual Network (6) 设置Azure Virtual Machine固定公网IP (Virtual IP Address, VIP) (1)...

《Windows Azure Platform 系列文章目录》 注意&#xff1a;本文介绍的是Global Azure (http://www.windowsazure.com)&#xff0c;如果你使用的是由世纪互联运维的Azure China&#xff0c;请参考下面的连接。 Azure China (8) 使用Azure PowerShell创建虚拟机&#xff0c;并设…

如何正确的学习Blender-入门到精通课程

流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |大小解压后:17.8 GB 含课程文件 |时长:21小时 27分 在Blender中学习3D建模、材质、灯光、渲染和动画&…

Java学习总结:47(打印流)

打印流 打印流包含字节打印流(PrintStream)和字符打印流(PrintWriter)。 例&#xff1a;定义打印流工具类 package Project.Study.PrintStream;import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream;class PrintUtil{ …