更新时间:2026-04-03
依赖文档:docs/features/windows-ai-desktop-control.md、docs/features/computer-use.md
在已有的 PowerShell 子进程方案基础上,利用 Windows 原生 API 增强 Computer Use 的 Windows 实现,解决 3 个核心问题:
- 窗口绑定截图:当前
CopyFromScreen只能全屏截图,无法对指定窗口截图(尤其是被遮挡/最小化窗口) - UI 结构感知:当前只能通过坐标点击,无法像 macOS Accessibility 那样理解 UI 元素树
- 性能:每次 PowerShell 启动约 273ms,剪贴板/窗口枚举等高频操作需要更快的方式
以下 API 全部通过 PowerShell P/Invoke 实测通过:
| 能力 | API | 验证结果 |
|---|---|---|
| 窗口绑定截图 | PrintWindow(hwnd, hdc, PW_RENDERFULLCONTENT) |
✅ VS Code 342KB, Chrome 273KB |
| 枚举窗口+HWND | EnumWindows + GetWindowText + GetWindowThreadProcessId |
✅ 38 个窗口,含 HWND/PID/标题 |
| UI 元素树 | System.Windows.Automation.AutomationElement |
✅ 记事本 39 个元素 |
| UI 写值 | ValuePattern.SetValue() |
✅ 成功写入记事本文本 |
| UI 点击 | InvokePattern.Invoke() |
✅ 按钮可程序化点击 |
| 坐标元素识别 | AutomationElement.FromPoint(x, y) |
✅ 返回元素类型+名称 |
| OCR | Windows.Media.Ocr.OcrEngine |
✅ 英语+中文引擎可用 |
| 全局热键 | RegisterHotKey |
✅ API 可调 |
| 剪贴板直接操作 | System.Windows.Forms.Clipboard |
✅ 读/写/图片检测 |
| Shell 启动 | ShellExecute |
✅ 打开文件/URL/应用 |
在现有 backends/win32.ts 基础上新增 Windows 专属模块:
packages/@ant/computer-use-input/src/
├── backends/
│ ├── darwin.ts ← 不动
│ ├── win32.ts ← 增强:直接 Win32 API 替代部分 PowerShell
│ └── linux.ts ← 不动
packages/@ant/computer-use-swift/src/
├── backends/
│ ├── darwin.ts ← 不动
│ ├── win32.ts ← 增强:PrintWindow 窗口截图 + EnumWindows
│ └── linux.ts ← 不动
packages/@ant/computer-use-mcp/src/
│ └── tools.ts ← 增加 Windows 专属工具定义(UI Automation、OCR)
src/utils/computerUse/
│ └── win32/ ← 新增目录:Windows 专属能力
│ ├── uiAutomation.ts ← UI 元素树、点击、写值
│ ├── ocr.ts ← 截图 + OCR 文字识别
│ ├── windowCapture.ts ← PrintWindow 窗口绑定截图
│ └── windowEnum.ts ← EnumWindows 窗口枚举
┌──────────────────────────────────────────────┐
│ Computer Use MCP Tools │
│ screenshot / click / type / request_access │
│ + Windows 专属: ui_tree / ocr / window_cap │
├──────────────────────────────────────────────┤
│ src/utils/computerUse/ │
│ executor.ts → 按平台 dispatch │
│ win32/ → Windows 专属能力模块 │
├──────────────────────────────────────────────┤
│ packages/@ant/computer-use-{input,swift} │
│ backends/win32.ts → PowerShell + Win32 API │
├──────────────────────────────────────────────┤
│ Windows Native API │
│ PrintWindow / EnumWindows / UI Automation │
│ SendInput / Clipboard / OCR / ShellExecute │
└──────────────────────────────────────────────┘
问题:当前 CopyFromScreen 只能全屏截图,无法对指定窗口截图。
方案:用 PrintWindow + FindWindow 实现窗口级截图。
| 步骤 | 文件 | 改动 |
|---|---|---|
| A.1 | src/utils/computerUse/win32/windowCapture.ts |
新建:captureWindow(title) 用 PrintWindow 截取指定窗口 |
| A.2 | src/utils/computerUse/win32/windowEnum.ts |
新建:listWindows() 用 EnumWindows 返回 {hwnd, pid, title}[] |
| A.3 | packages/@ant/computer-use-swift/src/backends/win32.ts |
screenshot.captureExcluding 增加按窗口截图能力 |
| A.4 | packages/@ant/computer-use-swift/src/backends/win32.ts |
apps.listRunning 用 EnumWindows 替代 Get-Process(返回 HWND) |
PowerShell 脚本核心:
# PrintWindow 截取指定窗口
Add-Type -AssemblyName System.Drawing
Add-Type -ReferencedAssemblies System.Drawing @'
using System; using System.Runtime.InteropServices; using System.Drawing; using System.Drawing.Imaging;
public class WinCap {
[DllImport("user32.dll", CharSet=CharSet.Unicode)]
public static extern IntPtr FindWindow(string c, string t);
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr h, out RECT r);
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr h, IntPtr hdc, uint f);
[StructLayout(LayoutKind.Sequential)]
public struct RECT { public int L, T, R, B; }
// ... CaptureByTitle(string title) → base64
}
'@验证标准:
- 能按窗口标题截图
- 被遮挡的窗口也能截图
- 返回 base64 + width + height
问题:macOS 有 Accessibility API 可以读取/操作 UI 元素,Windows 当前只能坐标点击。
方案:用 System.Windows.Automation 实现 UI 树读取和元素操作。
| 步骤 | 文件 | 改动 |
|---|---|---|
| B.1 | src/utils/computerUse/win32/uiAutomation.ts |
新建:核心 UIA 操作封装 |
| B.2 | packages/@ant/computer-use-mcp/src/tools.ts |
增加 Windows 专属工具定义 |
uiAutomation.ts 导出函数:
// 获取窗口的 UI 元素树
getUITree(windowTitle: string, depth: number): UIElement[]
// 按名称/类型/AutomationId 查找元素
findElement(windowTitle: string, query: {name?, controlType?, automationId?}): UIElement | null
// 点击元素(InvokePattern)
clickElement(windowTitle: string, automationId: string): boolean
// 设置元素值(ValuePattern)
setValue(windowTitle: string, automationId: string, value: string): boolean
// 获取坐标处的元素
elementAtPoint(x: number, y: number): UIElement | nullUIElement 类型:
interface UIElement {
name: string
controlType: string // Button, Edit, Text, List, etc.
automationId: string
boundingRect: { x: number, y: number, w: number, h: number }
isEnabled: boolean
value?: string // ValuePattern 可用时
children?: UIElement[]
}PowerShell 脚本核心:
Add-Type -AssemblyName UIAutomationClient
Add-Type -AssemblyName UIAutomationTypes
# 读取 UI 树
$root = [AutomationElement]::RootElement
$window = $root.FindFirst([TreeScope]::Children,
[PropertyCondition]::new([AutomationElement]::NameProperty, $title))
$elements = $window.FindAll([TreeScope]::Descendants, [Condition]::TrueCondition)
# 写入文本
$element.GetCurrentPattern([ValuePattern]::Pattern).SetValue($text)
# 点击按钮
$element.GetCurrentPattern([InvokePattern]::Pattern).Invoke()验证标准:
- 能读取记事本的 UI 树(按钮、文本框、菜单)
- 能向文本框写入内容
- 能点击按钮
- 能识别坐标处的元素
问题:截图后 AI 只能看到图片,无法直接读取文字。
方案:用 Windows.Media.Ocr 对截图进行文字识别。
| 步骤 | 文件 | 改动 |
|---|---|---|
| C.1 | src/utils/computerUse/win32/ocr.ts |
新建:截图 + OCR 识别 |
| C.2 | packages/@ant/computer-use-mcp/src/tools.ts |
增加 screen_ocr 工具定义 |
ocr.ts 导出函数:
// 对屏幕区域 OCR
ocrRegion(x: number, y: number, w: number, h: number, lang?: string): OcrResult
// 对指定窗口 OCR
ocrWindow(windowTitle: string, lang?: string): OcrResult
interface OcrResult {
text: string
lines: { text: string, bounds: {x,y,w,h} }[]
language: string
}已确认可用语言:英语 (en-US) + 中文 (zh-Hans-CN)
验证标准:
- 能识别屏幕区域中的英文和中文
- 返回文字内容 + 每行的位置信息
问题:每次 PowerShell 启动 273ms,鼠标移动等高频操作太慢。
方案:用 .NET System.Windows.Forms.Clipboard 等直接 API 替代 PowerShell 子进程。
| 步骤 | 文件 | 改动 |
|---|---|---|
| D.1 | src/utils/computerUse/executor.ts |
剪贴板操作用直接 API 替代 PowerShell |
| D.2 | 考虑驻留 PowerShell 进程 | 通过 stdin/stdout 交互,摊平启动成本 |
剪贴板直接 API(不需要 PowerShell 子进程):
# 读:50ms → <1ms
[System.Windows.Forms.Clipboard]::GetText()
# 写:50ms → <1ms
[System.Windows.Forms.Clipboard]::SetText($text)
# 图片检测
[System.Windows.Forms.Clipboard]::ContainsImage()问题:request_access 依赖 macOS bundleId 识别应用,Windows 没有这个概念。
方案:在 Windows 上用 exe 路径 + 窗口标题替代 bundleId。
| 步骤 | 文件 | 改动 |
|---|---|---|
| E.1 | packages/@ant/computer-use-mcp/src/toolCalls.ts |
resolveRequestedApps 在 Windows 上用 exe 路径匹配 |
| E.2 | packages/@ant/computer-use-mcp/src/sentinelApps.ts |
增加 Windows 危险应用列表(cmd.exe, powershell.exe 等) |
| E.3 | packages/@ant/computer-use-mcp/src/deniedApps.ts |
增加 Windows 浏览器/终端识别规则 |
| E.4 | src/utils/computerUse/hostAdapter.ts |
ensureOsPermissions Windows 上检查 UAC 状态 |
Windows 应用标识映射:
macOS bundleId → Windows 等价
com.apple.Safari → C:\Program Files\...\msedge.exe(或窗口标题匹配)
com.google.Chrome → chrome.exe
com.apple.Terminal → WindowsTerminal.exe / cmd.exe
问题:当前非 darwin 直接跳过 ESC 热键,用 Ctrl+C 替代。
方案:用 RegisterHotKey 或 SetWindowsHookEx(WH_KEYBOARD_LL) 实现。
| 步骤 | 文件 | 改动 |
|---|---|---|
| F.1 | src/utils/computerUse/escHotkey.ts |
Windows 分支:RegisterHotKey 注册 ESC |
优先级低——当前 Ctrl+C fallback 可用,ESC 热键是体验优化。
Phase A: 窗口绑定截图 ← P0 核心需求,解决"操作其他界面"
Phase B: UI Automation ← P0 核心能力,AI 理解 UI 结构
Phase C: OCR ← P1 增值能力,AI 读屏幕文字
Phase D: 性能优化 ← P1 体验优化,高频操作提速
Phase E: request_access 适配 ← P1 功能完整性,权限模型适配
Phase F: ESC 热键 ← P2 体验优化,可后做
| Phase | 新增文件 | 修改文件 | 新增代码行 | 风险 |
|---|---|---|---|---|
| A 窗口截图 | 2 | 1 | ~200 | 低 |
| B UI Automation | 1 | 1 | ~300 | 中 |
| C OCR | 1 | 1 | ~150 | 低 |
| D 性能优化 | 0 | 2 | ~50 | 低 |
| E request_access | 0 | 3 | ~100 | 中 |
| F ESC 热键 | 0 | 1 | ~50 | 低 |
| 总计 | 4 | 9 | ~850 | — |
backends/darwin.ts(两个包都不动)backends/linux.ts(两个包都不动)src/utils/computerUse/中 macOS 相关代码路径不动packages/@ant/computer-use-mcp/src/中已复制的参考项目代码不动(只追加 Windows 工具)
| 能力 | macOS | Windows (增强后) | Linux |
|---|---|---|---|
| 截图方式 | SCContentFilter (per-app) | PrintWindow (per-window) | scrot (全屏/区域) |
| UI 结构 | Accessibility API | UI Automation | 无 |
| OCR | 无内置 | Windows.Media.Ocr | 无内置 |
| 键鼠 | CGEvent + enigo | SendInput + keybd_event | xdotool |
| 窗口管理 | NSWorkspace | EnumWindows + Win32 | wmctrl |
| 剪贴板 | pbcopy/pbpaste | Clipboard 直接 API | xclip |
| ESC 热键 | CGEventTap | RegisterHotKey | 无 |
| 应用标识 | bundleId | exe 路径 + 窗口标题 | /proc + wmctrl |
Windows 增强后将在 UI Automation 和 OCR 方面超过 macOS 方案——这两项 macOS 原始实现也没有(Anthropic 用的是截图 + Claude 视觉理解,没有结构化 UI 数据)。