SendKeys与游戏:使用某些字符有效,但对某些字符无效

问题描述 投票:4回答:1

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

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

但是使用{ESC}无效。什么都没发生。如果我手动按下它,它将返回上一个菜单。 (应如此)

[在某些情况下,ESC起作用:

  • 它适用于Discord,Sourcetree,Slack,Chrome,CS2D,

  • 但是由于某些原因,它不适用于Minecraft,Spelunky,Half-Life。

上面提到的所有应用程序均处于窗口模式

另一个问题:

  • 如果我在文本字段中将2发送到Minecraft,它可以正常工作,将写入2。

  • 但是如果我在演奏时发送它,则没有效果。 (角色应切换到物品槽#2)

  • 与“相同(whitespace)。在文本字段中可以使用,但角色不会在游戏中跳转。

代码:

    [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时目标应用程序可以处于焦点。

结果相同:\

c# .net winapi input sendkeys
1个回答
1
投票

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

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

这意味着它不是Windows输入模拟器,而只是Windows Forms应用程序的一个小帮手。无法保证此方法可以与其他(不是.NET)运行时系统上的另一个进程一起使用。

尽管SendKeys.Send方法使用native Windows API,但它仅发送固定时间段的按键消息,因此游戏框架处理可能没有时间捕获此消息来进行管理。因此,您可能需要单独的命令来发送有关按键按下和按键按下事件的消息。

请勿将SendKeys API与其他进程(尤其是与游戏一起)进行消息传递”。此外,游戏可以使用保护系统来摆脱可能阻止来自操作系统编程输入的任何消息的自动漫游器,那么,您可以使用什么?

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

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.

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

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

还可以通过

lParam

设置关键消息的行为。请参见WM_KEYDOWNWM_KEYUP参数。关于WM_KEYDOWN消息的特殊之处在于,如果您长时间按真实键盘上的键,操作系统将相应地重复WM_KEYDOWN消息。可以通过lParam设置重复计数。如果您的消息传递窗口对单个按键消息没有反应,请使用它。PostMessage是低级系统命令,可用于进程之间的消息传递。该命令被保护系统阻止的可能性很小(但不为零),并且被您使用的游戏/进程接收的可能性很高。它还提供了分离按键和按键消息的机会。

如果PostMessage不起作用怎么办?

尝试使用

硬件扫描代码而不是虚拟键代码this answer中所述的详细说明。如果保护系统确实很好并且即使使用硬件扫描代码,PostMessage也会阻塞,那么您可以尝试

使用另一个键盘输入驱动程序

或自己编写。该驱动程序必须替换默认的系统键盘驱动程序。您可以向其发送消息以与游戏进行交互。这是通过键盘与其他进程进行交互的100%保证

方法。但是,如果您使用公共自定义键盘驱动程序,则保护系统很可能会阻止它。因此,您需要编写自己的驱动程序以在进程之间发送消息。
© www.soinside.com 2019 - 2024. All rights reserved.