桌面端
Midscene 通过原生键盘和鼠标控制,在 Windows、macOS 和 Linux 上自动化桌面应用。
本指南介绍平台配置、模型配置、Playground 体验,以及 @midscene/computer 的 JavaScript SDK 集成。
效果展示
提示词(macOS): 打开 Safari,发布一条介绍 Midscene 支持 AutoGLM 的推文,并使用“下载”文件夹中的 AutoGLM 视频。
查看完整报告,或浏览更多 Midscene 案例。
核心功能
跨平台桌面控制
- 鼠标操作:单击、双击、右键、移动和拖放。
- 键盘输入:输入文本 ,并使用 Cmd、Ctrl、Alt 或 Shift 执行组合按键。
- 屏幕截图:捕获任意显示器的画面。
- 多显示器:在一个工作流中操作多个显示器。
AI 驱动的自动化
使用自然语言指令自动化桌面应用:
await agent.aiAct('打开文件菜单');
await agent.aiAct('点击另存为');
await agent.aiAct('在文件名字段输入 "我的文档"');
await agent.aiAct('按回车键');
使用场景
- 测试 Electron、Qt 和原生桌面应用。
- 自动化桌面应用中的重复工作。
- 按顺序控制多个应用。
- 使用自然语言指令测试桌面界面。
快速开始
准备桌面环境
Node.js
需要 Node.js 18.19.0 或更高版本。
平台特定依赖
macOS:需要辅助功能权限才能控制键盘和鼠标。首次运行脚本时,macOS 会提示你授予访问权限。前往 系统设置 > 隐私与安全性 > 辅助功能,为运行脚本的应用程序(如 Terminal、iTerm2、VS Code、WebStorm 或其他 IDE)启用权限。更多详情请参阅 nut.js macOS 设置。
Windows:操作普通程序无需额外配置。但 Windows 会按权限级别隔离输入(UIPI):未提权的进程无法向以管理员身份运行(已提权)的窗口发送鼠标或键盘输入,输入会被静默丢弃——光标仍会移动到正确位置,但点击和按键不生效。优先尝试让目标程序不要以管理员权限运行;如果目标程序必须保持提权状态,再同样以管理员身份运行启动 Midscene 的终端或 Node.js,让两个进程处于相同的权限级别。详见 Windows:点击对某些程序不生效。
Linux:需要安装 ImageMagick 用于截图功能。
无头 Linux(CI 环境):要在无头 Linux 服务器(如 GitHub Actions)上运行桌面自动化,需安装 Xvfb 及其依赖,然后启用 headless 模式:
# 安装依赖
sudo apt-get install -y xvfb x11-xserver-utils imagemagick
// 方式 1:传入 headless 选项
const agent = await agentForComputer({ headless: true });
// 方式 2:设置环境变量
// MIDSCENE_COMPUTER_HEADLESS_LINUX=true npx tsx example.ts
Xvfb 会创建一个虚拟显示器,使鼠标、键盘和截图操作在没有物理显示器的情况下正常工作。详见 API 参考。
启动 Playground
Playground 是验证连接的最快方式。无需编写代码,即可体验 aiAct、aiQuery 和 aiAssert 等核心能力。它与 @midscene/computer 共享相同的核心,因此在 Playground 中通过的流程,在脚本中运行会保持一致。
- 启动 Playground CLI:
npx --yes @midscene/computer-playground
- 点击 Playground 窗口中的齿轮按钮,粘贴你的 API Key 配置。如果还没有 API Key,请回到 模型配置 获取。
使用 JavaScript SDK
当 Playground 运行正常后,就可以切换到可复用的 JavaScript 脚本。
配置模型
通过环境变量设置模型。选择模型时,请参考模型策略。
export MIDSCENE_MODEL_BASE_URL="https://替换为你的模型服务地址/v1"
export MIDSCENE_MODEL_API_KEY="替换为你的 API Key"
export MIDSCENE_MODEL_NAME="替换为你的模型名称"
export MIDSCENE_MODEL_FAMILY="替换为你的模型系列"
全部配置项请参考模型配置。
安装依赖
npm install @midscene/computer
yarn add @midscene/computer
pnpm add @midscene/computer
bun add @midscene/computer
deno add npm:@midscene/computer
编写脚本
创建 example.ts:
import { agentForComputer } from '@midscene/computer';
(async () => {
// 创建 agent
const agent = await agentForComputer({
aiActionContext: '你正在控制一台桌面计算机。',
});
// 截图并查询信息
const screenInfo = await agent.aiQuery(
'{width: number, height: number}, 获取屏幕分辨率'
);
console.log('屏幕分辨率:', screenInfo);
// 移动鼠标到中心
await agent.aiAct('将鼠标移动到屏幕中心');
// 断言屏幕有内容
await agent.aiAssert('屏幕有可见内容');
console.log('桌面自动化完成!');
})();
运行脚本
通过 RDP 连接远程 Windows 桌面
@midscene/computer 也可以通过专用的 agentForRDPComputer() 工厂,直接经由 RDP 协议控制远程 Windows 桌面。
前提条件
- 一台已开启 RDP 且网络可达的 Windows 机器。
- 在运行脚本的机器上安装 FreeRDP。
示例
import { agentForRDPComputer } from '@midscene/computer';
const agent = await agentForRDPComputer({
aiActionContext:
'You are controlling a remote Windows desktop over the RDP protocol.',
host: '10.75.166.249',
port: 3389,
username: 'Admin',
password: 'replace-with-your-password',
ignoreCertificate: true,
});
await agent.aiWaitFor('The remote Windows desktop is visible');
await agent.aiAct('Click the Windows Start button');
await agent.aiAct('Open Settings');
await agent.aiAssert('The Windows Settings window is visible');
常用 RDP 选项
host:远程 Windows 主机名或 IP。
port:RDP 端口,默认是 3389。
username / password:远程会话使用的账号凭据。
domain:可选的 Windows 域。
ignoreCertificate:用于跳过自签名证书校验。
desktopWidth / desktopHeight:请求指定远程桌面分辨率。
adminSession:当服务端 允许时,请求远程管理员会话。
对于 Midscene 来说,一个 RDP 会话会被视为单个远程显示器。你仍然可以像本机桌面自动化一样,使用 aiAct、aiQuery、aiAssert 和报告能力。
多显示器支持
如果您有多个显示器,可以控制特定的显示器:
import { ComputerDevice, agentForComputer } from '@midscene/computer';
// 列出所有显示器
const displays = await ComputerDevice.listDisplays();
console.log('可用显示器:', displays);
// 连接到特定显示器
const agent = await agentForComputer({
displayId: displays[0].id,
});
使用示例
基本鼠标操作
// 在屏幕中心点击
await agent.aiAct('在屏幕中心点击鼠标');
// 移动鼠标到特定位置
await agent.aiAct('将鼠标移动到左上角');
// 双击
await agent.aiAct('双击桌面图标');
// 右键
await agent.aiAct('右键打开上下文菜单');
键盘操作
// 输入文本
await agent.aiAct('输入 "你好世界"');
// 按快捷键
if (process.platform === 'darwin') {
await agent.aiAct('按 Cmd+Space 打开 Spotlight');
await agent.aiAct('输入 "计算器" 并按回车');
} else {
await agent.aiAct('按 Windows 键');
await agent.aiAct('输入 "计算器" 并按回车');
}
// 按功能键
await agent.aiAct('按 Escape');
await agent.aiAct('按 Enter');
查询信息
// 提取屏幕信息
const info = await agent.aiQuery(
'{hasDesktop: boolean, visibleApps: string[]}, 检查桌面是否可见并列出可见应用'
);
// 定位元素
const position = await agent.aiLocate('文件菜单');
console.log('文件菜单位置:', position);
复杂工作流
// 打开应用并与之交互
await agent.aiAct('打开访达');
await agent.aiWaitFor('访达窗口可见');
await agent.aiAct('点击文稿文件夹');
await agent.aiAct('按 Cmd+N 创建新文件夹');
await agent.aiAct('输入 "我的项目"');
await agent.aiAct('按回车');
await agent.aiAssert('存在名为 "我的项目" 的文件夹');
环境检查
您可以检查系统是否正确配置:
import { checkComputerEnvironment } from '@midscene/computer';
const env = await checkComputerEnvironment();
console.log('平台:', env.platform);
console.log('可用:', env.available);
console.log('显示器数量:', env.displays);
if (!env.available) {
console.error('环境不可用:', env.error);
}
常见问题
macOS:脚本无法控制鼠标或键盘
macOS 需要辅助功能权限才能控制键盘和鼠标。请前往 系统设置 > 隐私与安全性 > 辅助功能,为运行脚本的应用程序(如 Terminal、iTerm2、VS Code 或 WebStorm)开启权限。
如果已经授权但仍然无法控制,可以尝试将该应用从辅助功能列表中移除后重新添加——macOS 有时会缓存过期的权限。
Windows:点击对某些程序不生效
如果光标能移动到正确位置,但对某个程序点击或按键毫无反应,而其他程序却正常,请检查目标程序是否以管理员身份运行(已提权)。Windows 的 UIPI 机制会拦截由低权限进程注入到高权限窗口的输入,并静默丢弃,且不报任何错误。
优先尝试降低目标程序的权限级别,例如不要使用“以管理员身份运行”启动它,或关闭总是提权启动的相关设置。如果目标程序必须保持提权状态,再以管理员身份运行启动 Midscene 的终端(或 Node.js),使其与目标程序处于相同的权限级别,然后重试。像 Win+Tab 这类系统级快捷键由 shell 处理,即使在这种情况下也照常生效——这也是为什么有时键盘快捷键看起来能用、但程序内的点击却不行。
在 Windows 上,如果 Midscene 未以管理员身份运行,连接时的健康检查日志会打印这条排查文档链接。
Linux:在无头服务器上截图或交互失败
无头 Linux 环境(如 CI)没有物理显示器,需要安装 Xvfb 和 ImageMagick,并启用无头模式:
sudo apt-get install -y xvfb x11-xserver-utils imagemagick
const agent = await agentForComputer({ headless: true });
或通过环境变量设置:
MIDSCENE_COMPUTER_HEADLESS_LINUX=true npx tsx example.ts
下一步