C#实现向mumu模拟器内粘贴文本
之前使用SendKeys.SendWait("asfasf");的方式向模拟器中发送文本,但是有可能存在输入法干扰的问题
现在使用新的思路,将要发送的文本放到剪切板中,然后通过粘贴的方法粘贴到模拟器中,但是测试了几个方法无法粘贴成功,只会向模拟器中打一个空格,但使用SendInput扫描码方式可以粘贴成功
public static class PasteHelperScanCode
{
/// <summary>
/// 对当前获得焦点的窗口/控件执行一次粘贴(Ctrl+V,扫描码方式)
/// 前提:焦点已在目标输入框,且剪贴板内容已准备好
/// </summary>
public static void PasteCtrlV(int keyDelayMs = 15)
{
// 左Ctrl: 0x1D,V: 0x2F(常用 Set 1 扫描码)
const ushort SCAN_LCTRL = 0x1D;
const ushort SCAN_V = 0x2F;
INPUT[] inputs =
{
KeyDownScan(SCAN_LCTRL),
KeyDownScan(SCAN_V),
KeyUpScan(SCAN_V),
KeyUpScan(SCAN_LCTRL),
};
// 可选:某些模拟器对按键时序敏感,适当加一点间隔更稳
if (keyDelayMs > 0)
{
// 拆分发送:确保时序(有些窗口对一次性批量包不敏感)
foreach (var i in inputs)
{
SendOrThrow(new[] { i });
Thread.Sleep(keyDelayMs);
}
}
else
{
// 不需要延迟就一次性发完
SendOrThrow(inputs);
}
}
// ====== 内部实现 ======
private const int INPUT_KEYBOARD = 1;
private const uint KEYEVENTF_KEYUP = 0x0002;
private const uint KEYEVENTF_SCANCODE = 0x0008;
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
private static void SendOrThrow(INPUT[] inputs)
{
int cbSize = Marshal.SizeOf(typeof(INPUT));
uint sent = SendInput((uint)inputs.Length, inputs, cbSize);
if (sent != inputs.Length)
{
int err = Marshal.GetLastWin32Error();
throw new InvalidOperationException($"SendInput 失败,sent={sent}/{inputs.Length},Win32Error={err},cbSize={cbSize}");
}
}
private static INPUT KeyDownScan(ushort scan) => new INPUT
{
type = INPUT_KEYBOARD,
U = new InputUnion
{
ki = new KEYBDINPUT
{
wVk = 0, // 扫描码方式必须为 0
wScan = scan,
dwFlags = KEYEVENTF_SCANCODE,
time = 0,
dwExtraInfo = IntPtr.Zero
}
}
};
private static INPUT KeyUpScan(ushort scan) => new INPUT
{
type = INPUT_KEYBOARD,
U = new InputUnion
{
ki = new KEYBDINPUT
{
wVk = 0,
wScan = scan,
dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP,
time = 0,
dwExtraInfo = IntPtr.Zero
}
}
};
// ====== 关键:INPUT 的 union 必须包含三种成员,保证尺寸正确 ======
[StructLayout(LayoutKind.Sequential)]
private struct INPUT
{
public int type;
public InputUnion U;
}
[StructLayout(LayoutKind.Explicit)]
private struct InputUnion
{
[FieldOffset(0)] public MOUSEINPUT mi;
[FieldOffset(0)] public KEYBDINPUT ki;
[FieldOffset(0)] public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
private struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct HARDWAREINPUT
{
public uint uMsg;
public ushort wParamL;
public ushort wParamH;
}
}

浙公网安备 33010602011771号