【问题标题】:Programatically send keyboard input to graphical application (game) in Windows以编程方式将键盘输入发送到 Windows 中的图形应用程序(游戏)
【发布时间】:2015-01-15 04:40:02
【问题描述】:

我希望能够使用程序/脚本自动将键盘控制发送到一个非常简单的视频游戏。只有 3 个按钮需要工作,它们可以是任意 3 个键盘按钮(可以在游戏中更改键绑定)。控制基本上是左,右,射击。

我尝试过的事情: 蟒蛇:

  • keybd_event
  • 发送密钥
  • 发送输入

C++:

  • 使用 wVk 发送输入
  • SendInput 在 KEYEVENTF_SCANCODE 标志打开的情况下直接将十六进制扫描代码输入到 wScan
  • SendInput 使用 MapVirtualKey 为 wScan 转换字符(KEYEVENTF_SCANCODE 标志打开)

我几乎用谷歌搜索过这个问题,每个人都指向上述方法。它们都非常适合将文本输入记事本或其他文本输入(例如,向上箭头在命令提示符下工作正常,调出最后一个命令输入)。他们也可以很好地将角色发送到您将名字放在高分列表中的区域的游戏中。

我也可以在游戏运行时成功发送 F12(这会打开和关闭声音)。这至少表明,在实际游戏过程中,它正在接收键盘命令并明显正确地解释它们。

我无法实现的只是简单的动作命令(左、右、射击 - 简单游戏真正拥有的唯一命令)。我已经在游戏中使用设置为箭头键(默认)和“a”、“d”、“w”的命令进行了尝试,并通过其他应用程序验证了这些命令正在发送,以及(在字母的情况下)键)游戏本身内的高分输入屏幕。但它只是在实际游戏中没有注册它们。

我可以使用辅助功能菜单中的屏幕键盘发送击键来玩游戏。如果这样可行,似乎必须有某种方法来完成这个看似简单的任务,但我完全不知所措,搜索结果中充斥着错误的建议(上面列出的方法)。

任何人都可以为我指出一些可能有效的方向,而不是我已经尝试过的上面列出的事情之一,所有与此类似的问题的答案似乎都暗示了这一点?

如果有一种方法可以直接从 Python 执行此操作,那将是理想的,但如果真的需要,我可以处理其他语言。

快速代码 sn-p 示例:

#include <windows.h>

int main()
{   
    INPUT ip;

    // Time to focus the program
    Sleep(5000);

    ip.type = INPUT_KEYBOARD;
    ip.ki.dwFlags = KEYEVENTF_SCANCODE;

    //'w'
    ip.ki.wScan = 0x11;
    SendInput(1, &ip, sizeof(INPUT));

    ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
    SendInput(1, &ip, sizeof(INPUT));
    return 0;
}

这个简单的程序将在 5 秒后在记事本(或 cmd 或浏览器的地址栏或其他任何内容 - 任何文本输入似乎都可以正常工作)中输入字母“w”。现在,在游戏中,如果我有 '拍摄'设置为'w',它工作正常。如果我使用屏幕键盘并在那里按“w”,它就可以工作。但上述程序不会导致游戏中发生“射门”动作。 但是,如果我将扫描码更改为 0x58('F12'),程序将适当地在游戏中发出声音,就像我在实际键盘上按 F12 一样。

【问题讨论】:

  • getAsyncKeyState() 在 c++ 中可能会起作用,尽管你问的不是很清楚..
  • 绝对不是我要找的,抱歉。我不确定如何更清楚地解释。我正在尝试自动将键盘输入发送到 Windows 上的简单街机游戏。我想要一个可以为我输入“w”的程序。我发现许多方法(上面列出的)在简单的文本输入区域中可以很好地做到这一点,但在图形游戏中却不行。所有其他类似的问题似乎都遇到了和我一样的问题,收到了相同的(不工作的)建议,然后就沉默了,没有解决方案。
  • 你可以试试这个Windows Automation Framework

标签: python c++ windows input automation


【解决方案1】:

问题似乎在于,虽然文本输入通常会从缓冲区中提取输入,但实时游戏会错过像虚拟键盘一样快来来去去的按键。解决方案只是在按键和按键之间添加一个对 Sleep() 的简短调用。

此外,对于像我一样使用 Python 工作的任何人都尝试了经常建议的 SendKeys.py 但没有成功,请在代码中查找“playkeys”函数并在 key_down(vk) 之后添加 time.sleep(pause) ,这应该可以解决问题(它对我有用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 2020-05-14
    • 2012-01-22
    • 2023-03-10
    相关资源
    最近更新 更多