ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

cua 多光标后台计算机使用演示实战:用 cua-driver 并发驱动五种 UI 框架的“国家档案系统“

cua 多光标后台计算机使用演示实战:用 cua-driver 并发驱动五种 UI 框架的“国家档案系统“ cua 多光标后台计算机使用演示实战用 cua-driver 并发驱动五种 UI 框架的国家档案系统【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua本篇技术指南围绕仓库 samples/driver/multi-cursor 中的Multi-cursor background computer-use demoNational Records System展开一个前台主终端的人机操作会被实时转发到四个后台终端由四个独立的 cua-driver 会话即四个不同颜色的 Agent 光标并发执行全程不抬升任何窗口、不移动用户鼠标。读完本文你将掌握 cua-driver 在无自动化集成的遗留系统上做后台并发驱动的完整方法理解它如何在不依赖辅助功能树Accessibility Tree的情况下回退到像素级注入并学会构建、运行和扩展这样一个跨框架的演示编排器。演示要回答的核心问题在企业内网里大量政府、银行、制造类业务终端是纯手绘的遗留应用没有 API、没有插件接口、没有命令行甚至在 AI 时代完全没有自动化集成通道。这个 demo 想证明的是——这类应用 cua-driver 照样能自动化。它选择了一组刻意做旧的政府记录终端界面海军蓝横幅、UNCLASSIFIED // FOR OFFICIAL USE ONLY保密条、功能键栏、绿屏记录网格、状态栏。整个演示围绕三个能力点设计一对多的并发重放用户在中心主终端的一次操作输入账户名 点击 Add Record被同步扇出到四个角落的后台终端每个终端由独立的 cua-driver 会话驱动零干扰任何窗口都不会被抬到前台用户自己的鼠标指针从未被移动有无辅助功能树都能工作五个窗口横跨五种 UI 框架cua-driver 的默认分发逻辑在有 a11y 树的地方自动选择 UIA-Invoke在没有 a11y 树的地方回退到像素/指针注入。这正是 cua-driver 后台驱动能力的浓缩验证把每次操作都走无障碍接口与不得不走像素坐标的两类窗口放在同一张屏幕上同时驱动。窗口布局2×2 四角后台 居中主控每个窗口都是工作区的一半宽 × 一半高½ work-width × ½ work-height。四个角落窗口把任务栏安全的工作区taskbar-safe work area平铺成四个象限主控窗口居中并同时压住四个角落┌────────────────────────┬────────────────────────┐ │ Win32 GDI (NO a11y) │ WinForms (.NET) │ │ crimson ● │ amber ● │ │ ┌────────────────────────┐ │ │ │ MASTER — Win32 controls │ ← you │ ├───────────│ (foreground, overlaps) │─────────────┤ │ WPF (XAML)│ │ Electron │ │ └────────────────────────┘ mint_lime ● │ │ aqua ● │ (Chromium) │ └────────────────────────┴────────────────────────┘运行后在中心主控上点击SUBMIT或先输入一个 subject 名称再提交四个彩色光标会同时滑向四个角落终端并发地在后台提交同一条记录。观察每个角落的绿屏记录网格不断增长、RECORDS:计数器逐条跳动而没有任何角落窗口被带到前台。布局由编排器源码精确实现见 orchestrator/src/main.rs通过SystemParametersInfoW(SPI_GETWORKAREA)取工作区矩形失败时回退到GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN)计算每个象限的宽高四个角落窗口用SetWindowPos以SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOZORDER放置——不激活、不改变 Z 序主控窗口尺寸只有象限的一半放在工作区正中央恰好压住四角的中心接缝但不会遮住位于象限中心位置的表单主控窗口通过SetForegroundWindow置前交给人类操作。五种框架各测什么一张框架能力表窗口框架无障碍能力cua-driver 驱动路径TLWin32 GDI自绘无像素命中测试 → PostMessage / 指针注入TR.NET WinFormsMSAA/UIAUIA InvokeBL.NET WPFUIA (XAML)UIA Invoke通过WS_EX_NOACTIVATE避免抢占前台BRElectronUIA (Chromium)UIA InvokeCenterWin32 标准控件MSAA前台由人驱动每个角落节点的实现都放在 demo 目录内Win32 GDI 节点左上角crimson光标见 legacy-app/src/main.rs。它完全没有注册任何可访问性接口Account Name 字段和 Add Record 按钮都是WM_PAINT里用 GDI 画笔手绘的——这就是没有 a11y 树的极端情形只能走像素路径WinForms 节点右上角amber光标见 dotnet/winforms/Program.cs经典 Win32 控件 MSAA/UIAcua-driver 用 UIA Invoke 驱动 Account Name 文本框和 Add Record 按钮WPF 节点左下角aqua光标见 dotnet/wpf/Program.csXAML 元素树天然暴露 UIA且窗口带WS_EX_NOACTIVATE扩展样式确保 UIA Invoke 不会偷偷抢占前台Electron 节点右下角mint_lime光标见 electron/main.js 与 electron/index.htmlChromium 渲染进程暴露 UIA 树同样走 UIA Invoke中心主控见 legacy-app/src/main.rsAccount Name 是真实 Win32 EDIT 控件、SUBMIT 是真实 BUTTON 控件两者被埋点每当用户提交就把TYPE\ttext、CLICK\trx\try写到标准输出供编排器读取并重放。注意一个细节五种框架的界面布局是同一套分数化坐标。Win32 GDI 版用常量NAME/SAVE/DOODLE/GRID的客户端分数矩形见 legacy-app/src/main.rsWinForms 用X(a) W*a、Y(a) H*a的分数布局函数Electron 用grid-template-rows/columns百分比。这让编排器可以用客户端相对分数0~1统一计算像素目标跨框架复用同一套命中坐标。构建五步凑齐全部组件在 demo 目录samples/driver/multi-cursor下按顺序构建四类产物# from this directory cargo build # legacy-app orchestrator (Rust) dotnet build dotnet/winforms/winforms.csproj # WinForms dotnet build dotnet/wpf/wpf.csproj # WPF npm install --prefix electron # Electron (downloads electron once)还要在仓库根工作区把驱动本身构建一次cargo build -p cua-driver --manifest-path ..\..\libs\cua-driver\rust\Cargo.toml各产物说明Rust 侧demo 目录本身是一个 Cargo workspace见 Cargo.tomlmembers [legacy-app, orchestrator]一次cargo build同时产出legacy-app.exe和orchestrator.exe.NET 侧两个 csproj 分别产出winforms-legacy.exe与wpf-legacy.exe均放在各自bin/Debug/net10.0-windows/输出目录下编排器正是按这个路径探测可执行文件是否存在缺失时会打印(skip)并跳过该角落Electron 侧npm install --prefix electron只安装一次 Electron 运行时^39.8.5见 electron/package.json运行入口是electron .main.js。说明编排器对缺失的角落节点是容忍的。如果某个框架没构建或未安装它会打印[orch] (skip) ...继续运行——这非常适合先在只有 GDI 一个 .NET 节点的环境下快速试跑。运行人工驱动与自播放两种模式.\target\debug\orchestrator.exe # human-driven: click/type in the center .\target\debug\orchestrator.exe --auto # self-playing: drives a TYPECLICK every few seconds编排器启动后按这个顺序工作见 orchestrator/src/main.rs以cua-driver serve启动守护进程daemon依次拉起 legacy-app 的 GDI 角落、WinForms、WPF、Electron以及带 stdout 管道的中心主控通过窗口标题子串Win32 GDI/WinForms/WPF/Electron/Master (Win32用EnumWindows找到各窗口句柄轮询等待最多 8 秒按 2×2 象限布局放置角落主控居中置前对每个角落调用cua-driver call get_window_statecapture_mode:ax抓取辅助功能树在树中定位] EditAccount Name 字段和含ADD RECORD的] Button提交按钮——每个动作前都会重新抓取因为 Chromium 的树出现得晚、且随行数增加会重新编号而 GDI 永远没有树为每个会话预先启用彩色 Agent 光标cua-driver call set_agent_cursor_enabled {enabled:true,session:color}为每个角落开一个独立驱动线程每个线程通过mpsc::channel接收来自主控的动作并转发到对应cua-driver call会话。在人工模式下主控的 stdout 管道被BufReader逐行读取CLICK rx ry解析为点击动作、TYPE text解析为输入动作见 orchestrator/src/main.rs随后广播给所有角落线程。在--auto模式下编排器自己按3 秒 → TYPE SUBJECT-001..003 → 1.8 秒 → CLICK的节奏发送动作最后还会追加一轮画迷宫见下文。环境变量覆盖Env overrides默认路径写死在编排器里但以下变量可以覆盖CUA_DRIVER_EXEcua-driver 可执行文件路径默认libs/cua-driver/rust/target/debug/cua-driver.exe相对仓库根LEGACY_APP_EXElegacy-app 可执行文件路径默认target/debug/legacy-app.exe相对 demo 目录WINFORMS_EXE、WPF_EXE对应 .NET 产物路径ELECTRON_DIRElectron 应用目录。若CUA_DRIVER_EXE或LEGACY_APP_EXE不存在编排器直接报错退出cua-driver.exe not found at ...。进程清理Windows Job Object 兜底编排器启动的每个子进程守护进程、五个窗口都会通过AssignProcessToJobObject挂进一个设置了JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE的 Job Object见 orchestrator/src/main.rs。只要关掉中心窗口或杀掉编排器进程整个进程树会被 Windows 一次性回收不会有孤儿进程残留。动作分发有树走 UIA无树走像素每个角落线程对两类动作采用不同的路径见 orchestrator/src/main.rs输入Type有 a11y 树直接cua-driver call type_text并携带element_indexcua-driver 会自动路由到 UIAValuePattern.SetValue——不抢焦点、不投 SendInput无 a11yGDI 角落先把 Account Name 字段的分数位置FIELD_FRAC (0.28, 0.145)换算成窗口本地像素click一次聚焦再type_text发送WM_CHAR。点击Click有 a11y 树click携带 SUBMIT 按钮的element_index走 UIA Invoke无 a11y把主控发出的按钮相对中心rx/ry分数映射到 GDI 窗口本地像素再click。每次调用都以 JSON 传入pid、window_idHWND 地址和session例如{pid:1234,window_id:-1043813,element_index:7,text:SUBJECT-001,session:amber} {pid:1234,window_id:-1043813,x:420,y:180,session:crimson}校验Verify点击后线程会再抓一次get_window_state解析状态栏里的Records: N计数器只有计数器确实递增才判定COMMITTED ✓否则记录FAIL (no new record)。这是刻意设计的验证手段——只检查输入框里有文本很容易被骗必须证明记录真正落进了网格。GDI 角落的计数器是手绘像素、无法从树中读出因此它靠网格在屏幕上真实增长做可视化验证。画迷宫纯坐标拖拽 截图比对的自校验--auto模式的最后一幕是画迷宫用来证明 cua-driver 能在完全没有元素目标、没有应用配合的情况下仅靠坐标完成画布绘制见 orchestrator/src/main.rs迷宫是 7 段直线段组成的螺旋坐标定义在公共的REGION [0.470, 0.180, 0.900, 0.295]客户端分数矩形位于每个框架画板右上角每段调用一次cua-driver call drag参数带dispatch:backgroundcua-driver 能 PostMessage 的地方就 PostMessage 拖拽对会丢弃 posted mouse 的画布Chromium/WPF则回退到 pen 注入pointer*事件统一覆盖 mouse/pen/touch这正是 Electron 版用pointerdown/pointermove/pointerup而非mousedown的原因见 electron/index.html画完后通过get_window_statecapture_mode:visionWGC 采集连完全被遮挡的窗口也能截图把结果存成 PNG校验算法把绘制的墨迹和参考迷宫分别归一化到 96×96 网格用膨胀Chebyshev dilation 半径 2后的 F1 分数打分MAZE_PASS 0.45为及格线低于即判定FAIL (lines dont match)——且这个分数只评价线条形状不惩罚落点偏移和缩放。这里用到了两个值得注意的底层能力一是 WGCWindows Graphics Capture采集对遮挡窗口依然有效二是DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS)拿到的窗口外框尺寸用来把原始位图像素与截图缩放后像素对齐裁剪。彩色光标一个会话一种颜色cua-driver 会按会话名给每个 session 分配光标颜色调色板命名的会话如crimson直接选中对应颜色。每次click/type_text调用里带上session:color动作就被路由到该会话的叠加光标光标会滑行到目标位置。四个会话 → 四个光标同时动画。本 demo 用到的会话/颜色映射角落会话光标颜色Win32 GDIcrimsonWinFormsamberWPFaquaElectronmint_lime关于不抬升窗口no-z-raise的机制细节可进一步阅读仓库中的后台输入契约文档 the-no-foreground-contract.mdx以及 Windows 平台 MCP 工具清单 mcp-tools-windows.mdx。WPF 角落通过WS_EX_NOACTIVATE扩展样式从窗口层面保证 UIA Invoke 不会触发前台抢占这与 demo 的整体无前台契约一脉相承。从演示到生产可以复用的工程模式把 orchestrator/src/main.rs 当作模板可以提炼出几条可迁移的后台并发驱动模式会话隔离每个目标窗口一个独立 cua-driver 会话天然获得独立的彩色光标、独立的状态与校验上下文互不干扰每动作重发现get_window_state在每次动作前重新抓取并解析element_index规避了动态应用如 Chromium树编号漂移的问题——静态缓存索引在真实生产环境中几乎必坏可回退的分发策略把有树 → UIA无树 → 像素的决策放在动作执行层而不是启动层同一套编排代码可以同时服务两类窗口结果级校验用应用状态Records:计数器、截图比对而不是调用是否成功来判定动作是否真正生效进程树治理Job Object KILL_ON_JOB_CLOSE保证大规模多进程演示/测试不会留下孤儿进程。这套模式同样适用于仓库中的其他场景批量跑跨 OS 舰队cross-OS fleets评估、给 cua-bench 制造多窗口测试环境或把同一套人类一次操作 → 多 Agent 并发重放的范式用于数据生成与训练轨迹采集。演示的价值正在于它把 cua-driver 最容易被低估的后台、并发、无 a11y 也能干三件事压缩进了一个肉眼可见、可运行、可自校验的最小系统。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表