SendKeys with games: 对一些角色有效,但对某些角色无效

SendKeys with games: with some characters it works, but with some it doesn't

我想用SendKeys在游戏中模拟输入,但是我很难。

如果我将它与字母 T 一起使用,而 Minecraft 中的光标位于文本框(在主菜单中)中,它可以工作,字母 T 写在文本框。

但是使用 {ESC} 它不起作用。什么都没发生。如果我手动按下它,它会返回到上一个菜单。 (应该如此)

对于某些应用程序,ESC 有效:

上面提到的所有应用程序都是窗口模式

另一个问题:

代码:

    [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("USER32.DLL")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    public Form1()
    {
        InitializeComponent();
        IntPtr minecraftHandle = FindWindow("GLFW30", "Minecraft* 1.15.2");

        if (minecraftHandle == IntPtr.Zero)
        {
            MessageBox.Show("Minecraft is not running.");
            return;
        }

        SetForegroundWindow(minecraftHandle);
        SendKeys.SendWait("{ESC}");
    }

我在没有焦点切换的情况下尝试过:通过将 SendKey 调用分配给热键,因此在调用 SendKeys 时目标应用程序可以处于焦点。

结果是一样的:\

不要使用SendKeys.Send在不同运行时的进程之间进行消息传递

SendKeys.Send 方法来自 System.Windows.Forms 命名空间。

这意味着它不是Windows 输入模拟器,而只是Windows 表单应用程序的小帮手。不能保证此方法与不同(非 .NET)运行时系统上的另一个进程一起工作。

尽管SendKeys.Send方法使用了native Windows API,它只发送固定时间段的按键消息,所以游戏帧处理可能不会有时间赶上这条消息来管理它。因此,您可能需要单独的命令来发送有关按下和按下事件的消息。

不要使用 SendKeys API 与其他进程进行消息传递,尤其是游戏
此外,游戏可以使用保护系统来摆脱可以阻止来自操作系统编程输入的任何消息的自动机器人

那么,你可以使用什么?

首先,您可以尝试使用user32.dll系统库的PostMessage

const uint WM_KEYDOWN = 0x0100;
const uint WM_KEYUP = 0x0101;

[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

// hWnd - Window handler (can be getted by using GetForegroundWindow/FindWindow methods)
// msg - Key up/down message (WM_KEYUP / WM_KEYDOWN)
// wParam - Virual key code you need to pass to the window
// lParam - Additional parameter for set up key message behaviour.

所有虚拟键码都可以在微软文档网站上找到:
https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

别忘了在按键释放前需要等待一段时间。这是必需的,因为游戏缓存帧之间的输入,并且帧有固定的时间来捕获输入。只需在按下和按下消息之间写一些延迟。

您还可以通过lParam设置按键消息行为。请参阅 WM_KEYDOWN and WM_KEYUP 参数。 WM_KEYDOWN 消息的特殊之处在于,如果您长时间按下真实键盘上的键,操作系统会相应地重复 WM_KEYDOWN 消息。可通过 lParam 设置重复次数。如果 window 您的消息对单个按键消息没有反应,请使用它。

PostMessage 是低级系统命令,可用于进程间的消息传递。此命令被保护系统阻止的可能性很低(但不是零),并且被与您一起工作的 game/process 接收到的可能性很高。它还提供了分离按键消息和按键消息的机会。

如果 PostMessage 不起作用怎么办?

尝试使用硬件扫描码代替虚拟键码.

中描述的详细说明如何做到这一点

如果保护系统真的很好并且PostMessage即使你使用硬件扫描码也被阻止,你可以尝试的一件事是使用另一个键盘输入驱动程序或者自己写。该驱动程序必须替换默认的系统键盘驱动程序。您可以向它发送消息以与游戏互动。这是通过键盘与其他进程交互的 100% 保证 方式。但是,如果您使用 public 自定义键盘驱动程序,保护系统可能会阻止它。所以你需要自己写驱动来实现进程间的消息传递。