如何模拟键盘输入到远程桌面会话?

10

我正在尝试向运行在远程桌面会话中的应用程序发送虚拟键盘输入。我正在使用:

Byte key = Ord("A");

keybd_event(key, 0, 0, 0); // key goes down
keybd_event(key, 0, KEYEVENTF_KEYUP, 0); // key goes up

现在这段代码可以将字符“a”发送到任何本地窗口,但它无法发送到远程桌面窗口。这意味着我使用远程桌面连接到服务器,然后在该服务器上打开记事本。如果我手动按键盘:它们会出现在记事本的编辑器窗口中。但是keybd_event的虚拟键盘输入不会导致“a”出现在记事本中。如何从在本地机器上运行的应用程序向远程桌面连接中运行的应用程序编程地发送虚拟键盘输入?
吹毛求疵的角落:
在这种特殊情况下,我想这样做是因为我正在尝试打败空闲超时。但是我同样可以尝试执行UI自动化测试、UI压力测试、UI故障排除测试、UI单元测试、UI数据输入测试、UI绘图测试或UI弹性测试等。
换句话说,我想要这样做的原因并不重要。
注意:超时可能来自远程桌面不活动,也可能不是。我不知道,这不影响我的问题。
4个回答

7

答案

虽然微软表示您不需要发送OEM代码,而且您不应该,但您需要发送OEM扫描码。在这个例子中,我需要发送以下按键的OEM扫描码:

  • 按下A键
  • 松开A键

CodeProject上有一张图表列出了各种按键的制造和断开扫描码:

alt text

在我的情况下,原来对keybd_event的调用需要更改为:
Byte key = Ord("A");

keybd_event(key, 0x1E, 0, 0); // key goes down
keybd_event(key, 0x9E, KEYEVENTF_KEYUP, 0); // key goes up

我测试过了,它可以工作。所以一切都好。


3
使用 MapVirtualKey 比使用预制表格更好。 - P Daddy
@Piddy:我之前不知道这样一个API的存在,太好了!我一直想知道为什么OEM扫描表很难找到。可能是因为你可以向操作系统请求它们。 - Ian Boyd
甚至更好的是MapVirtualKeyEx()。 - Elmue

2

非常感谢,这个方法很有效。要获取键盘扫描码,可以使用以下代码:

int scan;
scan = MapVirtualKey(key & 0xff, 0);
keybd_event(key, scan, 0, 0); // key goes down
keybd_event(key, scan | 0x80, KEYEVENTF_KEYUP, 0); // key goes up

2
也许你可以使用轻量级的 telnet 替代工具 PsExec 在其他系统上执行 autoit 脚本,完全支持控制台应用程序的交互,无需手动安装客户端软件。
(AutoIt 可以向任何窗口应用程序发送任何信号(键或其他),并且可以在远程桌面上使用 PsExec 启动。)
例如,像 KillSaver 这样的 AutoIt 脚本旨在移动鼠标以避免计算机长时间处于闲置状态!

你不能在主桌面安装Autoit,将脚本编译成exe文件并在远程桌面上远程启动它吗? - VonC
keybd_event,你的意思是“我怎样可以从我的C++程序中以编程方式”发送[...]。不确定你是否可以(请参见http://www.tech-archive.net/Archive/VC/microsoft.public.vc.language/2005-01/0846.html)。 - VonC
编程语言是否有影响?不,我没有使用C、C++、C#或VB来编写我的程序。 - Ian Boyd
很好,我以为你被一种语言/技术限制了。那么我的答案依然有效。 - VonC
我现在明白你的意思了,你是对的。我应该更明确地说明我有一个Win32编程问题。 - Ian Boyd

0
你可以使用 SendMessage(); 它是一个更好的按键模拟器。 祝你好运!

你需要提供比这更多的信息。是哪个消息,带有什么wparam和lparam? - Ian Boyd
使用HWND window = FindWindow(classname, windowname); (您只需要其中一个; classname或windowname)SendMessage(window, wParam, lParam); (其中wParam是虚拟键(http://msdn.microsoft.com/en-us/library/aa926323.aspx),而lParam只是NULL) - Guus Geurkink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接