PerformClick() 是 WinForms 中模拟按钮点击最直接的方式,仅调用 Click 事件处理器,不触发鼠标相关副效应,禁用状态下仍执行;真实鼠标点击需用 SendInput API,但复杂且不稳定;WPF 或跨进程场景推荐 UIAutomation。

WinForms 里用 PerformClick() 模拟按钮点击最直接
多数时候你不需要“自动点击”,而是想让按钮逻辑立刻执行——PerformClick() 就是为此设计的。它不触发鼠标事件,只调用按钮绑定的 Click 事件处理器,干净、可控、无副作用。
- 仅适用于 WinForms 的
Button控件,WPF 或 Web 不适用 - 不会改变焦点、不触发
MouseEnter等副效应,适合单元测试或逻辑驱动场景 - 如果按钮被禁用(
Enabled = false),PerformClick()仍会执行事件处理器——这点常被忽略,可能引发意料外的状态变更 - 示例:
myButton.PerformClick();
需要真实鼠标点击?得用 SendInput API,但别轻易上
真正模拟鼠标按下/释放动作,绕过控件逻辑、触发所有底层事件(包括焦点切换、悬停反馈),必须调 Windows API SendInput。但它代价高、不稳定、容易被 UAC 或屏幕锁定阻断。
- 必须在 UI 线程调用,且目标窗口需处于前台(或至少未最小化)
- 坐标是屏幕绝对坐标,不是控件相对位置——算错一个像素就点歪
- 多显示器、DPI 缩放、远程桌面下坐标极易偏移,调试困难
- 示例关键步骤:先用
GetWindowRect获取按钮屏幕坐标,再计算中心点,最后封装INPUT结构体调用SendInput
WPF 或跨进程场景?优先考虑 UIAutomation 而非模拟点击
如果你面对的是 WPF、UWP、甚至第三方软件(如微信、钉钉),UIAutomation 是微软官方支持的无障碍自动化方案,比硬点坐标靠谱得多。
- 依赖控件暴露
AutomationId或名称,没设就很难定位——开发时就得预留 - 需要引用
UIAutomationClient和UIAutomationTypes程序集 - 调用
InvokePattern.Invoke()等效于点击,比SendInput更健壮,但启动慢、对低权限进程可能失败 - 常见报错:
ElementNotAvailableException(元素已销毁)、InvalidOperationException(模式不支持)
为什么不用 Selenium 或 AutoIt?C# 项目里它们反而更重
Selenium 是为浏览器设计的,AutoIt 是独立脚本语言——硬塞进 C# 工程,等于引入额外进程、IPC 开销和部署负担。除非你已经在用它们做端到端测试,否则纯 C# 场景下没必要。
- Selenium 需启动浏览器驱动,无法操作本地 WinForms/WPF 窗口
- AutoIt 脚本要编译或解释执行,调试链路断裂,错误堆栈不回溯到 C# 代码
- 两者都增加安装依赖项,CI/CD 流水线变复杂,普通工具类需求杀鸡用牛刀
实际写的时候,绝大多数“自动点击”需求本质是“触发业务逻辑”,PerformClick() 足够;真要模拟人手操作,先确认是否必须——很多问题其实该从 UI 设计或事件解耦去解决,而不是在点击动作上死磕。








