keybd_event:全局击键模拟在c#控制台以意想不到的方式显示
本文关键字:控制台 意想不到 显示 方式 模拟 event 全局 keybd | 更新日期: 2023-09-27 17:53:22
当您打开控制台并按住a
按钮一秒钟时会发生什么?
输出最好是aaaaaaaa +- a few a's
。因此,当我模拟按下a
按钮并在一秒钟后释放它时,如果发现这段代码的输出很奇怪:
static void Main(string[] args)
{
keybd_event(0x41, 0, KEYEVENTF_KEYDOWN, 0);
Thread.Sleep(1000);
keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
Console.ReadLine();
}
为单个a
。好吧,我可以接受。我将做一个循环来重复这个任意次数。假设我需要5次使用a
字符,我希望下面的代码就足够了:
static void Main(string[] args)
{
const int VK_A = 0x41;
for (int i = 0; i < 5; i++)
{
keybd_event(VK_A, 0, KEYEVENTF_KEYDOWN, 0);
keybd_event(VK_A, 0, KEYEVENTF_KEYUP, 0);
Thread.Sleep(200);
}
Console.WriteLine("done");
Thread.Sleep(4000);
Console.ReadLine();
}
我很惊讶输出是
done
aaaaa
请注意,"完成"是在 a
's之前,我觉得很奇怪,当Console.ReadLine()
到达....时,a
's同时出现好像那个语句触发了字母出现....如果您想自己尝试,您还需要:
[DllImport("user32.dll", EntryPoint = "keybd_event", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern void keybd_event(byte vk, byte bscan, uint flags, int extrainfo);
const int KEYEVENTF_KEYUP = 0x2;
const int KEYEVENTF_KEYDOWN = 0x0;
我有完全相同的问题与较新的功能SendInput
。有人能给我解释一下这背后的逻辑吗?
听起来输出缓冲区在击键之间没有刷新。这里有一个类似的帖子:
c#或。net刷新键盘缓冲区
帖子指出,冲洗键盘实际上是不可能的。网上有一些关于如何做到这一点的帖子——大多数类似于:http://myarticles-csharpnetstuff.blogspot.com/2009/09/tip-flush-keyboard-buffer-in-c.html
并使用以下方法(从链接复制):
private static void FlushKeyboard()
{
while (Console.In.Peek() != -1)
Console.In.Read();
}
我个人不喜欢这种方式,因为你最终会做很多不必要的读操作。你到底想干什么?"aaaa"出现在"done"之前真的很重要吗?
——丹