VB.NET鼠标点击操作程序代码:用TaoToken统一Key接入AI辅助生成与调试

发布时间:2026/10/15 18:46:16
VB.NET鼠标点击操作程序代码:用TaoToken统一Key接入AI辅助生成与调试
1. VB.NET 鼠标点击程序代码到底怎么写从 Win32 API 到 SendInput 的完整落地VB.NET 鼠标点击程序代码说白了就是让桌面程序替你去点鼠标——指定坐标、按下左键、抬起左键必要时再拖一段距离。它适合做自动化测试、批量表单填写、重复性桌面操作脚本也适合给内部工具加一个一键执行按钮。很多人第一次写会直接抄一段mouse_event的代码跑起来发现坐标偏了、点击没反应、或者程序卡死问题基本都出在坐标系、DPI 缩放和线程阻塞这三件事上。我这次把两种主流方案都写清楚一种是经典的SetCursorPosmouse_event代码短、上手快另一种是SendInput结构体多一点但更贴近系统底层、兼容性更好尤其在多显示器和高 DPI 环境下更稳。两种方案我都会给出可直接复制的 VB.NET 函数并且演示怎么用 TaoToken 的统一 Key 调 AI 接口来辅助生成和纠错这些代码——比如你写完SendInput结构体不确定字段顺序对不对或者报错reading choices不知道怎么改都可以让 AI 帮你过一遍。先明确一个概念VB.NET 里操作鼠标不是靠 .NET 类库而是通过 P/Invoke 调用user32.dll里的 Win32 API。SetCursorPos负责把光标移到屏幕绝对坐标mouse_event和SendInput负责模拟按键事件。屏幕坐标原点在左上角X 向右增大Y 向下增大单位是像素。听起来简单但如果你在 125% 或 150% 缩放的显示器上跑拿到的坐标和实际点击位置会对不上这是最常见的坑后面第 5 节会专门讲。这篇文章的节奏是这样先讲清楚问题场景和两种方案的取舍再讲怎么用 TaoToken 拿到统一 Key 并配好环境然后给出完整可复制的配置和代码接着验证点击是否真的生效再排查几个高频报错最后给一个接入文档和 API Keys 的入口。全程按能跟着做来写不堆概念。2. 用 TaoToken 统一 Key 接入 AI 辅助生成与调试 VB.NET 点击代码写 Win32 API 调用最烦的不是逻辑是细节MOUSEEVENTF_LEFTDOWN的值是H2还是2INPUT结构体里dwType和mi的嵌套顺序DllImport的CharSet要不要加。这些细节记不住很正常让 AI 帮你生成一版再对照修改效率高很多。TaoToken 在这里的作用是提供一个统一的 API Key你不用为不同模型分别申请和切换 Key一个 Key 就能调对话模型来生成代码、解释报错、做代码审查。TaoToken 是什么它是一个统一的大模型 API 接入服务把多个模型的调用收敛到一套 Base URL 和 Key 上。能做什么你可以用它调模型对话来生成 VB.NET 代码片段、让它解释SendInput结构体、或者把一段报错贴进去让它给修复建议。适合谁适合正在写桌面自动化、又不想在多个平台之间来回折腾 Key 的开发者。接入前你需要准备三样东西这也是后面所有配置的基础我把它叫三件套配置项值说明Base URLhttps://taotoken.net/api所有请求的统一入口不要加 UTM 参数API Key在控制台创建形如sk-开头的一串字符只显示一次记得保存Model ID按需选择例如对话类模型 ID填在请求体的model字段拿 Key 的路径很直接打开控制台进 API Keys 页面创建一个新 Key复制保存。控制台地址是https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsoleAPI Keys 页面是https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys。创建完 Key 之后如果你想先在网页上试试模型能不能正常回话可以去模型对话页面https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat发一条消息验证。这里要提醒一句Key 是敏感信息不要硬编码进 VB.NET 源码然后提交到仓库。建议放在环境变量或者单独的配置文件里代码里读配置。下面第 3 节我会给出具体的读取方式。环境准备方面你需要在 Visual Studio 里新建一个 Windows Forms App (.NET Framework) 项目目标框架选 4.7.2 或更高都行。项目建好后Imports System.Runtime.InteropServices是必须的因为 P/Invoke 依赖这个命名空间。如果你用的是 .NET 6/7/8 的 WinFormsDllImport的写法基本一致但要注意SendInput的INPUT结构体在 64 位下的大小对齐问题这个后面会讲。为什么用 AI 辅助而不是纯手写SendInput的INPUT联合体在 VB.NET 里要用StructLayout(LayoutKind.Explicit)加FieldOffset来模拟字段偏移写错一个整个调用就静默失败——不报错但鼠标不动。这种问题靠肉眼很难查把结构体贴给 AI 让它核对偏移量几分钟就能定位。这就是统一 Key 接入的实际价值不是替代你写代码而是帮你把容易错的细节过一遍。3. 可复制的 VB.NET 鼠标点击配置与代码SetCursorPos 与 SendInput 双方案这一节是核心给出完整可复制的代码。先讲配置再讲两种方案的实现。3.1 把 Base URL、Key、Model ID 写进配置文件在项目根目录建一个appsettings.json.NET Framework 项目可以手动读或者用My.Settings。内容如下{ TaoToken: { BaseUrl: https://taotoken.net/api, ApiKey: sk-你的Key粘贴在这里, ModelId: 你的模型ID } }如果你不想引入 JSON 解析库用最简单的My.Settings也行在项目属性里加三个字符串设置项TaoTokenBaseUrl、TaoTokenApiKey、TaoTokenModelId。代码里这样读Dim baseUrl As String My.Settings.TaoTokenBaseUrl Dim apiKey As String My.Settings.TaoTokenApiKey Dim modelId As String My.Settings.TaoTokenModelId注意 Base URL 结尾不要带斜杠请求路径拼接时统一用/v1/chat/completions这种形式。Key 不要写死在Form1.vb里。3.2 方案一SetCursorPos mouse_event 实现点击这是最经典的写法代码短。先声明 APIImports System.Runtime.InteropServices Imports System.Threading Public Class MouseClickHelper DllImport(user32.dll) Private Shared Function SetCursorPos(ByVal x As Integer, ByVal y As Integer) As Boolean End Function DllImport(user32.dll) Private Shared Sub mouse_event(ByVal dwFlags As Integer, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As IntPtr) End Sub Private Const MOUSEEVENTF_LEFTDOWN As Integer H2 Private Const MOUSEEVENTF_LEFTUP As Integer H4 Private Const MOUSEEVENTF_RIGHTDOWN As Integer H8 Private Const MOUSEEVENTF_RIGHTUP As Integer H10 summary 在指定屏幕坐标执行一次左键单击 /summary Public Shared Sub LeftClick(ByVal x As Integer, ByVal y As Integer, Optional ByVal delayMs As Integer 50) SetCursorPos(x, y) Thread.Sleep(delayMs) mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, IntPtr.Zero) Thread.Sleep(delayMs) mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, IntPtr.Zero) End Sub summary 右键单击 /summary Public Shared Sub RightClick(ByVal x As Integer, ByVal y As Integer, Optional ByVal delayMs As Integer 50) SetCursorPos(x, y) Thread.Sleep(delayMs) mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, IntPtr.Zero) Thread.Sleep(delayMs) mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, IntPtr.Zero) End Sub End Class调用方式MouseClickHelper.LeftClick(500, 300)这里有个关键点mouse_event的dwExtraInfo参数类型我用的是IntPtr而不是原示例里的Integer。在 64 位系统上用Integer会有隐患IntPtr更安全。另外Thread.Sleep的延迟不要省按下和抬起之间至少留 30 到 50 毫秒否则某些程序会识别不到点击。3.3 方案二SendInput 实现点击推荐SendInput比mouse_event更底层微软官方也建议新代码用SendInput。它需要定义INPUT、MOUSEINPUT结构体Imports System.Runtime.InteropServices Imports System.Threading Public Class SendInputHelper StructLayout(LayoutKind.Sequential) Private Structure MOUSEINPUT Public dx As Integer Public dy As Integer Public mouseData As UInteger Public dwFlags As UInteger Public time As UInteger Public dwExtraInfo As IntPtr End Structure StructLayout(LayoutKind.Sequential) Private Structure INPUT Public type As UInteger Public mi As MOUSEINPUT End Structure DllImport(user32.dll, SetLastError:True) Private Shared Function SendInput(ByVal nInputs As UInteger, ByVal pInputs() As INPUT, ByVal cbSize As Integer) As UInteger End Function DllImport(user32.dll) Private Shared Function SetCursorPos(ByVal x As Integer, ByVal y As Integer) As Boolean End Function Private Const INPUT_MOUSE As UInteger 0 Private Const MOUSEEVENTF_LEFTDOWN As UInteger H2 Private Const MOUSEEVENTF_LEFTUP As UInteger H4 Private Const MOUSEEVENTF_ABSOLUTE As UInteger H8000 Public Shared Sub LeftClick(ByVal x As Integer, ByVal y As Integer, Optional ByVal delayMs As Integer 50) SetCursorPos(x, y) Thread.Sleep(delayMs) Dim inputs(1) As INPUT inputs(0).type INPUT_MOUSE inputs(0).mi.dwFlags MOUSEEVENTF_LEFTDOWN inputs(1).type INPUT_MOUSE inputs(1).mi.dwFlags MOUSEEVENTF_LEFTUP Dim sent As UInteger SendInput(2UI, inputs, Marshal.SizeOf(GetType(INPUT))) If sent 2UI Then Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()) End If End Sub End Class调用和方案一一样SendInputHelper.LeftClick(500, 300)。两种方案的取舍我用表格对比一下对比项SetCursorPos mouse_eventSendInput代码量少中等兼容性一般部分新程序不响应好官方推荐多显示器需额外处理支持绝对坐标报错可查基本静默可通过 GetLastWin32Error 查推荐场景快速脚本生产级自动化如果你只是临时写个脚本点几下方案一够用如果要做长期运行的自动化工具直接上方案二。3.4 用 TaoToken 调 AI 生成和纠错代码拿到 Key 之后你可以用 VB.NET 的HttpClient发请求。下面是一个最小可用的调用函数Imports System.Net.Http Imports System.Text Imports Newtonsoft.Json.Linq Public Class AiHelper Public Shared Async Function AskAsync(prompt As String) As Task(Of String) Dim baseUrl As String My.Settings.TaoTokenBaseUrl Dim apiKey As String My.Settings.TaoTokenApiKey Dim modelId As String My.Settings.TaoTokenModelId Using client As New HttpClient() client.DefaultRequestHeaders.Add(Authorization, Bearer apiKey) Dim body As New JObject() body(model) modelId Dim messages As New JArray() messages.Add(New JObject() From { {role, user}, {content, prompt} }) body(messages) messages Dim content As New StringContent(body.ToString(), Encoding.UTF8, application/json) Dim resp As HttpResponseMessage Await client.PostAsync(baseUrl /v1/chat/completions, content) Dim text As String Await resp.Content.ReadAsStringAsync() If Not resp.IsSuccessStatusCode Then Throw New Exception(请求失败 resp.StatusCode text) End If Dim json As JObject JObject.Parse(text) Return json(choices)(0)(message)(content).ToString() End Using End Function End Class用法示例让它帮你核对SendInput结构体Dim reply As String Await AiHelper.AskAsync( 下面这段 VB.NET 的 SendInput 结构体定义字段偏移和类型是否正确 vbCrLf MOUSEINPUT: dx Integer, dy Integer, mouseData UInteger, dwFlags UInteger, time UInteger, dwExtraInfo IntPtr)返回的内容会告诉你字段顺序和类型是否匹配。如果它指出问题你直接改代码就行。这就是统一 Key 接入的用法把容易错的细节交给模型核对你负责集成和验证。4. 验证点击坐标与事件触发怎么确认代码真的点到了代码写完不代表能跑通必须验证。验证分三步先确认坐标对不对再确认点击事件有没有触发最后确认目标程序有没有响应。4.1 验证坐标先读再点写一个读当前鼠标坐标的函数用GetCursorPosStructLayout(LayoutKind.Sequential) Public Structure POINTAPI Public X As Integer Public Y As Integer End Structure DllImport(user32.dll) Public Shared Function GetCursorPos(ByRef lpPoint As POINTAPI) As Boolean End Function在窗体上放一个Timer间隔 100 毫秒刷新一次把坐标显示在Label上Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick Dim p As POINTAPI GetCursorPos(p) Label1.Text X p.X Y p.Y End Sub运行程序把鼠标移到你想点击的目标位置记下Label上的坐标。这个坐标就是你要传给LeftClick的值。注意如果你在缩放不是 100% 的显示器上这里读到的坐标是物理像素坐标而SetCursorPos接受的也是物理像素坐标两者一致所以直接用没问题。但如果你用Control.MousePosition读拿到的可能是逻辑坐标会偏所以统一用GetCursorPos。4.2 验证点击事件用一个测试窗体接收建一个测试用的 WinForms 窗体上面放一个按钮按钮的Click事件里弹一个MessageBox。然后用你的点击代码去点这个按钮的坐标。如果弹窗出现说明点击生效。Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click MessageBox.Show(点击已触发) End Sub先手动点一次确认按钮正常再用代码点。代码点的时候把按钮的屏幕坐标算出来Dim screenPos As Point Button1.PointToScreen(New Point(Button1.Width \ 2, Button1.Height \ 2)) SendInputHelper.LeftClick(screenPos.X, screenPos.Y)PointToScreen把控件内坐标转成屏幕坐标取中心点更稳。如果弹窗出现说明整条链路通了。4.3 验证目标程序响应用记事本做端到端测试打开记事本把窗口移到固定位置用代码点击记事本的编辑区然后检查光标有没有落进去。更严格的测试是点击菜单项比如点格式菜单看菜单有没有展开。这一步能验证点击是否被目标程序真正接收而不只是被系统记录。如果前两步都通过、第三步失败通常是目标程序以管理员权限运行而你的程序不是Windows 的 UIPI 机制会拦截跨权限的输入。解决办法是让你的程序也以管理员身份运行在app.manifest里设置requestedExecutionLevel levelrequireAdministrator。4.4 用 AI 辅助排查验证失败如果点击没反应把现象描述给 AI比如VB.NET SendInput 调用返回 2但目标程序没响应目标程序是管理员权限它会提示你检查 UIPI 和权限。这种排查用统一 Key 调模型很快不用自己翻文档。5. 本篇常见报错排查401、local proxy failed、reading choices、OAuth这一节列几个高频报错和对应处理。这些报错分两类一类是调 AI 接口时的一类是鼠标点击本身的。5.1 401 Unauthorized调 TaoToken 接口返回 401说明 Key 不对或没带上。检查三件事请求头里Authorization是不是Bearer加 Key中间有一个空格Key 有没有复制完整前后有没有多余空格Key 是不是已经被删除或过期。在控制台重新创建一个 Key 再试。注意 Base URL 用https://taotoken.net/api不要拼错。5.2 local proxy failed这个报错通常出现在你本地配了代理但代理没启动或者端口不对。检查你的HttpClient有没有走系统代理如果不需要代理在HttpClientHandler里设UseProxy False。另外确认你的网络环境能正常访问taotoken.net用浏览器打开模型对话页面试试能不能加载。5.3 reading choices 报错这个报错一般是你解析返回 JSON 时choices字段不存在或者结构不对。常见原因请求失败但你没检查状态码就直接解析或者模型返回的是流式格式你按非流式解析。处理办法是先打印原始返回文本确认结构再取choices(0).message.content。如果返回体里是error字段说明请求本身有问题先解决错误再解析。5.4 OAuth 相关报错如果你用的是某些需要 OAuth 授权的客户端工具报 OAuth 错误通常是回调地址或 token 过期。这类工具一般支持直接填 API Key 的方式优先用 Key 方式接入避免 OAuth 流程。如果必须用 OAuth检查系统时间是否准确时间偏差过大会导致 token 校验失败。5.5 鼠标点击本身的报错SendInput返回 0 而不是 2说明调用失败。用Marshal.GetLastWin32Error()拿错误码。常见错误码 5 是权限不足错误码 87 是参数错误结构体大小不对。结构体大小用Marshal.SizeOf(GetType(INPUT))算64 位下应该是 40 字节32 位下是 28 字节。如果算出来不对检查MOUSEINPUT里dwExtraInfo是不是IntPtr。另一个高频问题是点击坐标偏移。如果你在 150% 缩放的屏幕上用Control.MousePosition拿到的坐标和SetCursorPos需要的坐标不一致。统一用GetCursorPos读、SetCursorPos写两者都是物理像素就不会偏。5.6 三件套检查清单如果你用 Cline、CC Switch 或 Codex 这类工具接入配置里必须写全三件套Base URL 填https://taotoken.net/apiKey 填你创建的 KeyModel ID 填你要用的模型。少任何一个都会报错。Codex 的auth.json里对应字段是base_url、api_key、modelCC Switch 里是baseUrl、apiKey、modelCline 的 MCP 配置里是baseUrl、apiKey、modelId。字段名不同值是一样的。6. 长期做桌面自动化用 Coding Plan 更省心如果你只是偶尔写一段点击代码按上面的步骤配好 Key 就够了。但如果你要长期做桌面自动化、批量脚本、或者把 AI 辅助集成到日常开发流程里每次手动管 Key、切模型会比较烦。TaoToken 的 Coding Plan 就是为这种场景准备的它把编码相关的调用打包成一个长期可用的方案适合持续写代码、跑 Agent 的开发者。入口在https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan。回到代码本身最后给你一个实用技巧把LeftClick和RightClick封装成带重试的版本。因为桌面程序响应有快有慢单次点击可能落空。加一个重试循环点完检查目标状态没变就再点一次最多三次。这个模式在自动化里很常见比单纯加长Thread.Sleep更可靠。Public Shared Sub LeftClickWithRetry(ByVal x As Integer, ByVal y As Integer, ByVal checkFunc As Func(Of Boolean), Optional ByVal maxRetry As Integer 3) For i As Integer 1 To maxRetry LeftClick(x, y) Thread.Sleep(300) If checkFunc() Then Return Next Throw New Exception(点击后状态未变化已重试 maxRetry 次) End SubcheckFunc是你自己写的判断函数比如检查某个窗口标题变了、某个文本框有内容了。这样点击就不是盲点而是有反馈的闭环。写自动化最怕的就是以为点到了其实没点到加个检查函数能省很多调试时间。接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdocAPI Keys 在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys。先把 Key 建好把上面的AiHelper跑通再回头调你的点击代码顺序别反。