SendInput失败主因是INPUT结构体初始化不全或事件不成对:type字段未设、键盘/鼠标关键字段缺失、按下与释放未配对、组合键时序错误、UIPI权限隔离。

SendInput 函数调用失败,返回 0 怎么办
直接调用 SendInput 却没任何反应,多数情况是输入结构体初始化不完整或缺少关键字段。Windows 要求每个 INPUT 结构的 type 字段必须显式设为 INPUT_KEYBOARD 或 INPUT_MOUSE,且后续字段必须按对应类型严格填充——比如鼠标事件漏填 mi.dwFlags,键盘事件没设 ki.wVk 或 ki.dwFlags,都会导致整个批次被静默丢弃。
实操建议:
立即学习“C++免费学习笔记(深入)”;
直播话术巡检系统(Windows版) — 实时语音转写、关键词检测、场景自动切换、告警推送、大屏可视化。支持 Windows VB-Cable 虚拟声卡音频采集,阿里云 ASR 实时识别。一键启动脚本,自动安装环境。
- 始终用
ZeroMemory或memset初始化整个INPUT数组,避免未初始化内存影响判断 - 键盘事件中,按下和释放必须成对出现;若只发一个
KEYEVENTF_KEYUP,系统会忽略(因为无对应按下) - 鼠标事件注意坐标单位:默认是屏幕绝对坐标(需设
MOUSEEVENTF_ABSOLUTE),但值范围是 0–65535;若想用像素坐标,得先用GetSystemMetrics(SM_CXSCREEN)换算 - 调用后检查返回值是否等于传入的事件数,不等说明部分或全部被拒绝——常见于前台窗口拥有更高 UIPI 级别(如以管理员身份运行的目标程序)
模拟 Ctrl+C 这类组合键为什么按不出来
组合键不是“同时按多个键”,而是有明确时序:先按修饰键(VK_CONTROL),再按功能键(VK_C),然后释放功能键,最后释放修饰键。任意顺序错乱、遗漏释放,目标应用都收不到有效组合键。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用四个
INPUT结构按顺序构造:Ctrl 按下 → C 按下 → C 释放 → Ctrl 释放 - 不要依赖
KEYEVENTF_SCANCODE配合虚拟键码混用;优先统一用wVk(如VK_CONTROL、VK_C),更稳定 - 如果目标是控制台或某些沙盒应用,还需确保调用进程与目标窗口处于同一桌面(
WTSQueryUserToken+SetThreadDesktop可能必要,但属进阶场景) - 测试时可用记事本+任务管理器验证:先激活记事本,再运行代码,观察是否真触发复制
鼠标点击没反应,但坐标是对的
最常被忽略的是:点击动作需要“按下 + 释放”两个事件,且中间不能有延迟(否则被识别为拖拽)。另外,如果目标窗口最小化或被遮挡,SendInput 仍会向桌面发送事件,但目标窗口未必接收——它只保证事件进入系统输入队列,不保证被特定窗口处理。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 鼠标左键点击必须包含
MOUSEEVENTF_LEFTDOWN和MOUSEEVENTF_LEFTUP两个事件,缺一不可 - 避免在
SendInput前后加Sleep;系统内部已做去抖,人为延迟反而破坏时序 - 确认目标窗口已获得输入焦点:可用
SetForegroundWindow尝试激活,但注意 Windows 10/11 对后台激活有限制(需用户最近交互过该窗口) - 调试时可用
GetCursorPos+ScreenToClient验证最终坐标是否落在目标控件客户区内
为什么管理员权限下才能模拟到某些程序
UIPI(User Interface Privilege Isolation)机制会阻止低完整性级别进程向高完整性级别窗口发送输入事件。例如:你用普通权限运行的程序,无法通过 SendInput 向以管理员身份运行的记事本发送按键——这不是 SendInput 的 bug,而是 Windows 安全设计。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 检查自身进程完整性级别:
OpenProcessToken+GetTokenInformation读取TOKEN_ELEVATION - 若必须跨级操作,唯一合规路径是让目标程序主动暴露 IPC 接口(如 WM_COPYDATA、命名管道),由高权限进程监听并转发输入
- 开发阶段可临时关闭 UIPI 测试(仅限调试!):修改注册表
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System下EnableUIADesktopToggle为 1,但重启后失效且不推荐生产环境使用

















