# WinAutomatic-Mcp **Repository Path**: zhouke17/win-automatic-mcp ## Basic Information - **Project Name**: WinAutomatic-Mcp - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-02 - **Last Updated**: 2026-07-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # WinApp-MCP **FlaUI + MCP** 的 Windows 桌面应用自动化工具,将 FlaUI (Windows UI Automation 封装)暴露为 Model Context Protocol (MCP) 服务器,供 Claude Desktop/Code 调用。 ## 功能 - ✅ 启动/附加 Windows 应用 (WinForms/WPF/UWP/Win32) - ✅ 查找控件 (by AutomationId/Name/ClassName) - ✅ 点击/输入文本 - ✅ 读取控件属性 (Name/IsEnabled/IsVisible) - ✅ 获取控件树 (便于调试) - ✅ stdio 传输(轻量,启动快) ## 系统要求 - Windows 10/11 - .NET 8 Runtime (或 SDK) - 目标应用需支持 UI Automation (大多数现代 Windows 应用都支持) ## 快速开始 ### 1. 编译 ```bash cd WinAppMcp dotnet build ``` ### 2. 手工测试(stdio 模式) ```bash dotnet run ``` 然后手工输入 JSON-RPC 请求(用于调试): ```json {"jsonrpc":"2.0","id":1,"method":"initialize","params":{}} {"jsonrpc":"2.0","id":2,"method":"tools/list"} {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"launch_app","arguments":{"path":"notepad.exe"}}} ``` ### 3. 在 Claude Desktop 中配置 编辑 `%APPDATA%\Claude\claude_desktop_config.json`: ```json { "mcpServers": { "winapp": { "command": "dotnet", "args": [ "run", "--project", "E:\\code\\WinApp-MCP\\WinAppMcp\\WinAppMcp.csproj" ] } } } ``` 或者用编译后的 exe: ```json { "mcpServers": { "winapp": { "command": "E:\\code\\WinApp-MCP\\WinAppMcp\\bin\\Debug\\net8.0-windows\\WinAppMcp.exe" } } } ``` ### 4. 在 Claude Code(VS Code) 中配置 编辑 `.vscode/settings.json`(或全局 settings): ```json { "mcp.servers": { "winapp": { "command": "dotnet", "args": ["run", "--project", "E:\\code\\WinApp-MCP\\WinAppMcp\\WinAppMcp.csproj"] } } } ``` 重启 VS Code,工具会自动加载。 ## 工具列表(14 个) ### 应用生命周期 | 工具名 | 功能 | 参数示例 | |--------|------|----------| | `launch_app` | 启动应用 | `{"path": "notepad.exe"}` | | `attach_by_name` | **附加到已运行的进程** | `{"process_name": "notepad"}` | | `close_app` | 关闭应用 | `{"app_handle": "app_0"}` | | `list_windows` | 列出窗口 | `{"app_handle": "app_0"}` | ### 控件查找 | 工具名 | 功能 | 参数示例 | |--------|------|----------| | `find_element` | 查找控件 | `{"app_handle": "app_0", "by": "name", "value": "文件"}` | | `wait_for` | **轮询等待控件出现(默认 10s)** | `{"app_handle": "app_0", "by": "name", "value": "确认", "timeout_seconds": 15}` | | `get_tree` | 获取控件树(调试用) | `{"app_handle": "app_0"}` | ### 交互操作 | 工具名 | 功能 | 参数示例 | |--------|------|----------| | `click` | 左键点击 | `{"element_handle": "elem_0"}` | | `right_click` | **右键点击(触发上下文菜单)** | `{"element_handle": "elem_0"}` | | `drag_drop` | **拖拽(控件到控件)** | `{"from_handle": "elem_0", "to_handle": "elem_1"}` | | `type_text` | 输入文本 | `{"element_handle": "elem_1", "text": "Hello"}` | ### 读取信息 | 工具名 | 功能 | 参数示例 | |--------|------|----------| | `get_property` | 读控件属性 | `{"element_handle": "elem_0", "property": "Name"}` | | `get_text` | **专门读取文本内容** | `{"element_handle": "elem_0"}` | | `screenshot` | **窗口截图(base64 PNG,供视觉识别)** | `{"app_handle": "app_0"}` | > **粗体**为新增工具。 ## 高级场景示例 ### 场景 A: 截图 + 视觉识别 ``` 帮我截图记事本,看看有没有错误提示 Claude 内部调用: 1. attach_by_name: notepad → app_0 2. screenshot: app_0 → 返回 PNG base64 3. Claude 视觉模型分析图像内容 ``` ### 场景 B: 异步等待登录框 ``` 打开应用后等待登录框出现,然后填写账号密码 Claude 内部调用: 1. launch_app: myapp.exe → app_0 2. wait_for: {app_0, "name", "登录", timeout_seconds: 15} → elem_0 3. find_element: 用户名输入框 → elem_1 4. type_text: elem_1, "admin" 5. find_element: 密码输入框 → elem_2 6. type_text: elem_2, "password" 7. find_element: 登录按钮 → elem_3 8. click: elem_3 ``` ### 场景 C: 附加已运行的应用 ``` 用户已开好 iflyCourt.exe,帮我检查主界面控件 Claude 内部调用: 1. attach_by_name: iflyCourt → app_0 2. get_tree: app_0 → 输出控件树 3. Claude 根据树结构定位下一步操作 ``` ## 使用示例 在 Claude 中: ``` 启动记事本并输入 Hello World: 1. launch_app: notepad.exe 2. find_element: by=class, value=Edit 3. type_text: "Hello World" ``` Claude 会自动调用对应工具完成操作。 ## 故障排查 **问题**: `应用句柄无效` / `元素句柄无效` **原因**: MCP 是无状态协议,每次调用后句柄保留在服务器内存中。如果服务器重启,句柄会清空。 **解决**: 重新 launch_app 获取新句柄。 --- **问题**: `未找到元素: name=按钮` **原因**: 1. 控件名称拼写错误 2. 控件还未渲染(应用启动慢) 3. 控件在子窗口/对话框中 **解决**: 1. 先用 `get_tree` 查看实际控件名称 2. 等待几秒后再查找 3. 用 `by=class` 或 `by=id` 代替 `by=name` --- **问题**: 编译时 `CS0104: Application 不明确引用` **解决**: 已在 `.csproj` 中去掉 `true`,避免 System.Windows.Forms.Application 冲突。 --- **问题**: `screenshot` 返回空白图像 **原因**: 1. 目标窗口被最小化 2. 窗口被其他窗口完全遮挡(部分应用截图依赖前台绘制) **解决**: 1. 先用 `find_element` + `click` 激活窗口,或调用 Windows API 恢复 2. 关闭遮挡窗口后重试 --- **问题**: `wait_for` 超时错误(`等待超时: name=xxx (10s)`) **原因**: 1. 控件名称拼写错误(区分大小写和空格) 2. 控件延迟加载超过 10 秒 3. 控件在不同窗口中(如模态对话框) **解决**: 1. 先用 `get_tree` 确认实际名称 2. 增大 `timeout_seconds` 参数(如 30) 3. 用 `by=id` 或 `by=class` 尝试不同查找方式 --- **问题**: `drag_drop` 拖拽后目标应用无响应 **原因**: 目标是 UWP 应用或禁用了 Drop 操作(部分安全沙箱应用) **解决**: 1. UWP 应用无解,属平台限制 2. 检查目标控件是否有 Drop Pattern:`get_property` 读取属性列表 ## 架构说明 ``` stdin (JSON-RPC) → Program.cs → FlaUI.UIA3 → Windows UI Automation ↓ Target WinForms/WPF App ``` - **句柄缓存**: `_apps` 字典缓存 `Application` 对象,`_elements` 缓存 `AutomationElement`,通过 GUID 引用。 - **超时机制**: `GetMainWindow` 默认 5 秒超时,避免应用启动慢时卡死。 - **错误日志**: 所有日志输出到 `stderr`,不污染 stdout 的 JSON-RPC 流。 ## 扩展 可以添加的工具: - `screenshot`: 截图返回 base64(MCP 支持 image content) - `wait_for`: 等待控件出现(轮询 + 超时) - `drag_drop`: 拖拽操作 - `get_text`: 读取 TextBox/Label 文本(当前用 `get_property` 实现) - `attach_by_name`: 通过进程名附加(如 `notepad` → 查找 notepad.exe) ## 依赖 - [FlaUI](https://github.com/FlaUI/FlaUI) 5.0 — Windows UI Automation 封装 - .NET 8 — 跨平台运行时(仅 Windows 目标) - [MCP Protocol](https://modelcontextprotocol.io/) 2024-11-05 ## 许可 MIT License --- **作者**: 由 Claude 生成(2025-07-01) **项目地址**: E:\code\WinApp-MCP