You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SendKeys.SendWait()与Electron交互:如何设置DOM3键盘事件code属性?

解决Electron游戏键盘自动化中DOM事件code属性为空的问题

问题核心

用C#的SendKeys.SendWait("a")给Electron游戏模拟按键时,虽然DOM事件触发了,但事件的code属性是空字符串,游戏因为校验这个属性直接忽略了输入;而物理键盘按"A"时,code会被正确设为KeyA,游戏能正常响应。这是因为SendKeys是高层API,生成的事件缺少硬件级的扫描码数据,Chromium(Electron基于它)无法据此填充code字段。

可行方案:用Win32 API的SendInput模拟硬件级按键

SendInput能生成更接近物理键盘的输入事件,关键是要设置扫描码和KEYEVENTF_SCANCODE标志,让Chromium识别并填充正确的code属性。

实现步骤

  1. 导入Win32 API的结构体和函数定义:
using System;
using System.Runtime.InteropServices;

public class HardwareKeyboardSimulator
{
    [StructLayout(LayoutKind.Sequential)]
    private struct INPUT
    {
        public uint Type;
        public INPUTUNION Data;
    }

    [StructLayout(LayoutKind.Explicit)]
    private struct INPUTUNION
    {
        [FieldOffset(0)]
        public KEYBDINPUT Keyboard;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct KEYBDINPUT
    {
        public ushort Vk;
        public ushort Scan;
        public uint Flags;
        public uint Time;
        public IntPtr ExtraInfo;
    }

    private const uint INPUT_KEYBOARD = 1;
    private const uint KEYEVENTF_SCANCODE = 0x0008;
    private const uint KEYEVENTF_KEYUP = 0x0002;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

    // 发送带扫描码的按键事件(按下+抬起)
    public static void PressKey(ushort scanCode)
    {
        INPUT downEvent = new INPUT
        {
            Type = INPUT_KEYBOARD,
            Data = new INPUTUNION
            {
                Keyboard = new KEYBDINPUT
                {
                    Scan = scanCode,
                    Flags = KEYEVENTF_SCANCODE
                }
            }
        };

        INPUT upEvent = new INPUT
        {
            Type = INPUT_KEYBOARD,
            Data = new INPUTUNION
            {
                Keyboard = new KEYBDINPUT
                {
                    Scan = scanCode,
                    Flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP
                }
            }
        };

        INPUT[] events = new[] { downEvent, upEvent };
        SendInput((uint)events.Length, events, Marshal.SizeOf(typeof(INPUT)));
    }
}
  1. 调用方法模拟按键
    比如模拟"A"键,直接传入它的扫描码0x1E:
// 触发A键对应的游戏技能
HardwareKeyboardSimulator.PressKey(0x1E);

扫描码获取

常用按键的扫描码可以查标准键盘扫描码表,或者用Win32的MapVirtualKey函数转换虚拟键码得到:

  • A: 0x1E
  • S: 0x1F
  • D: 0x20
  • W: 0x11

注意事项

  • 如果游戏以管理员权限运行,你的C#程序也必须用管理员权限启动,否则SendInput可能无法生效。
  • 部分游戏有反作弊机制,可能会拦截模拟输入,这种情况下需要进一步调整(比如使用驱动级模拟,但难度更高)。
  • Chromium会给SendInput生成的事件设isTrusted=true,能避开大部分基于该属性的校验。

内容的提问来源于stack exchange,提问作者ben_makes_stuff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:52:36