C#怎么模拟鼠标点击 C#如何调用WindowsAPI干货最佳实践|Duuu笔记
优先使用 SendInput 模拟鼠标点击,因其兼容高 DPI、多显示器和 UIPI;若必须用 mouse_event,需归一化坐标至 0–65535 并用 MOUSEEVENTF_ABSOLUTE。
怎么用
mouse_event
模拟鼠标点击(C#)
Windows API 的
mouse_event
已废弃,但仍在 .NET Framework 项目中常见。它不区分高 DPI 缩放,也不支持多显示器坐标偏移,直接调用容易点偏或失效。
实操建议:
优先改用
SendInput
—— 它是微软当前推荐的输入模拟方式,兼容 DPI、多屏、UIPI(用户界面特权隔离)
若必须用
mouse_event
,确保传入屏幕绝对坐标(
MOUSEEVENTF_ABSOLUTE
),且把坐标归一化到 0–65535 范围:
(int)(x * 65535.0 / screen.Width)
不要在 WPF 或 WinForms 的 UI 线程里直接调用,避免被 UI 线程挂起或触发安全拦截;建议用
Task.Run
包一层
C# 调用
SendInput
的最小可用写法
SendInput
需要构造
INPUT
结构体,最容易出错的是字段对齐、
dwType
类型误设、以及未清零 padding 字段导致内存越界。
关键点:
INPUT
必须用
[StructLayout(LayoutKind.Sequential)]
,且显式指定
SizeConst = 28
(x64 下)或
24
(x86)
鼠标事件必须设
dwType = 0
,然后用
dwFlags
组合:比如左键按下是
MOUSEEVENTF_LEFTDOWN
,抬起是
MOUSEEVENTF_LEFTUP
坐标参数
dx
/
dy
是相对还是绝对,取决于是否设置了
MOUSEEVENTF_ABSOLUTE
;绝对坐标下单位是 0–65535,不是像素
调用前检查返回值:如果
SendInput
返回 0,说明输入被系统拦截(如锁屏、UAC 提权窗口前台)或结构体格式错误
示例片段(仅左键单击):
var input = new INPUT { type = 0, mi = new MOUSEINPUT { dx = 10000, dy = 10000, dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN } };
SendInput(1, ref input, INPUT.Size);
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP;
SendInput(1, ref input, INPUT.Size);
为什么模拟点击在远程桌面或最小化窗口里经常失效
不是代码写错了,而是 Windows 的输入模型限制:默认情况下,
SendInput
和
mouse_event
只能向「当前活动桌面」和「前台进程」投递输入。远程桌面会切到自己的会话桌面,而程序最小化时通常失去前台焦点。
白瓜AI
白瓜AI,一个免费图文AI创作工具,支持 AI 仿写,图文生成,敏感词检测,图片去水印等等。
下载
应对方式:
确认目标窗口是否处于活跃桌面(
GetThreadDesktop
+
OpenInputDesktop
可查,但需权限)
用
SetForegroundWindow
+
BringWindowToTop
尝试激活目标窗口(不一定成功,尤其跨会话或高完整性级别进程)
真正可靠的方案是注入目标进程并调用其内部消息循环(如
PostMessage
发送
WM_LBUTTONDOWN
),但这需要目标窗口句柄和消息结构知识,且受 UIPI 限制
自动化测试场景建议换用 UI Automation(
System.Windows.Automation
),它绕过输入队列,直接调用控件的
InvokePattern
WPF/WinForms 程序里别用 API 模拟点击来“触发按钮逻辑”
这是最常被忽略的陷阱:你用
SendInput
点了界面上的按钮,但按钮的
Click
事件根本没执行。因为 UI 框架的事件是靠消息泵解析
WM_COMMAND
或路由事件触发的,API 级点击只产生原始鼠标消息,不走框架事件链。
正确做法:
WinForms:直接调用
button.PerformClick()
WPF:获取按钮的
ICommand
或手动触发
button.RaiseEvent(new RoutedEventArgs(Button.ClickEvent))
只有当你确实需要测试「真实鼠标行为」(比如验证鼠标坐标响应、拖拽反馈、第三方控件兼容性)时,才动用 Windows API
跨进程、跨会话、高 DPI、UAC、多显示器——这些不是边缘情况,是日常环境。API 模拟点击不是“写完就能跑”,得先想清楚你要模拟的是「输入动作」本身,还是「点击带来的业务效果」。后者几乎永远有更稳的替代路径。
