1. 使用.Net Framework的库函数
SendKeys.SendWait("123{TAB}abc");
namespace System.Windows.Forms命名空间下的SendKeys是.Net提供的模拟键盘输入的工具类。其中有Send()和SendWait()这两个方法,都可以发送按键消息。区别在于SendWait()是会等待按键消息被处理完成才返回的,而Send()则不用。这就类似于SendMessage和PostMessage的关系。
上面代码中的{TAB}代表Tab键。键盘上一些特殊的按键都有对应的代码,具体的对照表可以参照微软MSDN上的介绍:SendKeys Class
当然,还可以使用Windows API,API原型如下:
/// <summary>
/// 合成一次击键事件
/// </summary>
/// <param name="bVk">定义一个虚拟键码。键码值必须在1~254之间</param>
/// <param name="bScan">定义该键的硬件扫描码</param>
/// <param name="dwFlags">定义函数操作的各个方面的一个标志位集。应用程序可使用如下一些预定义常数的组合设置标志位</param>
/// <param name="dwExtraInfo">定义与击键相关的附加的32位值</param>
[DllImport("user32")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
uint dwExtraInfo);
甚至用SendMessage和PostMessage也是可以做到的。
但以上这些实现方法都是在Windows消息层面的,对于像记事本等常规应用程序是没问题的。但是对于一些游戏、QQ登录框、网银登录框等则无效。这是因为这些程序不是从Windows消息中获取按键信息的,而是直接从底层驱动层面获取按键信息的。
在一篇关于研究游戏外挂的博文里看到博主描述了这个问题:
引自:https://blog.csdn.net/zdrl/article/details/12707835
在解释更详细的原理之前,我们先来抓出幕后黑手,看看是哪个给游戏撑腰?让它有胆子违抗Windows消息命令。究竟是判断了真实键盘信息,还是有其他原因。结果在DirectX编程中发现了DirectInput这个API。就是它绕过了Windows的消息机制,它的目的是为了让游戏的实时性控制更好、更快。Windows消息是队列形式的,在传递过程中会有延时,比如格斗类游戏对实时性控制要求是非常高的,Window消息机制不能满足这个需求。而DirectInput直接和键盘驱动程序打交道,效率当然要高出一大截。我认为大部分游戏不响应消息的真正的原因在这里,而不是故意写了反作弊系统。
2. 使用WinIO.dll
由于上述方法只能模拟Windows消息层面的按键,以至于对一些应用程序无效,所以下面就采用直接在驱

本文介绍了C#模拟键盘输入的三种方法:1) 使用.Net Framework库函数,如SendKeys;2) 利用WinIO.dll直接在驱动层面操作,适用于32位和64位系统,但需要管理员权限和特定键盘类型;3) 使用WinRing0x64.dll,相比WinIO更便捷,同样要求管理员权限和PS/2键盘。文中还提供了相关Demo和参考资料。

8410

被折叠的 条评论
为什么被折叠?



