SendKeys.Send() 无反应的根本原因是目标窗口未激活或焦点缺失,需确保窗体已激活、UI线程调用且控件就绪;WPF中应改用WindowsInput库;防检测需模拟人工输入节奏并结合UIA或直接设值。

SendKeys.Send() 为什么按了没反应?
多数人卡在这一步:调用 SendKeys.Send("{TAB}") 或 SendKeys.Send("{ENTER}") 后,焦点没动、表单没提交。根本原因不是代码写错,而是当前线程没获得输入焦点,或者目标窗口处于非活动/最小化状态。
- 必须确保目标窗体(比如 WinForm 的
TextBox所在窗体)已激活且可见——this.Activate()或form.BringToFront()不能少 - UI 线程需处于可交互状态:不能在后台线程直接调用
SendKeys;若在异步任务中触发,得用Invoke()回 UI 线程 - 某些安全上下文(如以管理员权限运行的程序去操作非管理员窗口)会静默拦截
SendKeys,此时改用keybd_event或SendInputAPI 更可靠
WinForms 中自动填表 + Tab 切换的典型流程
填表不是“发键”就完事,关键是控制节奏和校验控件状态。例如一个登录页有 txtUsername、txtPassword、btnLogin,顺序填完后要回车提交。
- 先用
txtUsername.Focus()显式获取焦点,再SendKeys.Send("admin"),避免因控件未 ready 导致字符丢失 - 每个
SendKeys.Send("{TAB}")后建议加Application.DoEvents()(仅调试期),让 UI 有时间响应焦点变更;生产环境更推荐用await Task.Delay(50)配合 async/await -
SendKeys.Send("{ENTER}")前确认按钮是否Enabled == true且Visible == true,否则可能触发无响应或异常
WPF 里没法直接用 SendKeys?试试 InputSimulator
WPF 默认不支持 SendKeys(尤其 .NET Core/.NET 5+),强行用会抛 InvalidOperationException。这不是 bug,是 WPF 输入模型与 Win32 消息循环隔离导致的。
- 推荐引入开源库
WindowsInput(NuGet 包名:WindowsInput),它封装了底层SendInputAPI,跨框架兼容性好 - 填表示例:
var sim = new InputSimulator(); sim.Keyboard.TextEntry("test"); sim.Keyboard.KeyPress(VirtualKeyCode.TAB); - 注意:WPF 控件焦点管理更严格,
TextBox.Focus()返回true才代表真正获得焦点;失败时得检查IsTabStop、Focusable属性是否为true
自动化填表容易被识别为机器人?绕过检测的关键点
很多网页表单或 Electron 应用内置防自动化逻辑,比如监听 keydown 事件中 event.isTrusted === false,或检测输入间隔是否过于均匀。
- 纯
SendKeys或InputSimulator发出的按键默认isTrusted = false,会被前端 JS 拦截——此时必须用 UIA(UI Automation)或直接设置控件Text属性(WinForms)/TextBox.Text(WPF) - 避免“秒填”:人工输入通常有停顿、删改。模拟时加入随机延迟(如
Task.Delay(Random.Next(80, 200)))比固定值更安全 - 别忽略鼠标行为:有些系统要求先点击输入框再输入。用
sim.Mouse.MoveMouseTo(...)+sim.Mouse.LeftButtonClick()补全动作链
真正的难点不在“怎么发键”,而在“什么时候发、发给谁、发完怎么确认”。焦点切换的时机差 100ms,整个流程就可能卡死——这没法靠文档解决,得看实际窗口消息日志。


















