• 简体中文
  • 桌面端

    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 是验证连接的最快方式。无需编写代码,即可体验 aiActaiQueryaiAssert 等核心能力。它与 @midscene/computer 共享相同的核心,因此在 Playground 中通过的流程,在脚本中运行会保持一致。

    1. 启动 Playground CLI:
    npx --yes @midscene/computer-playground
    1. 点击 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
    yarn
    pnpm
    bun
    deno
    npm install @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('桌面自动化完成!');
    })();

    运行脚本

    npx tsx example.ts

    通过 RDP 连接远程 Windows 桌面

    @midscene/computer 也可以通过专用的 agentForRDPComputer() 工厂,直接经由 RDP 协议控制远程 Windows 桌面。

    前提条件

    1. 一台已开启 RDP 且网络可达的 Windows 机器。
    2. 在运行脚本的机器上安装 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 会话会被视为单个远程显示器。你仍然可以像本机桌面自动化一样,使用 aiActaiQueryaiAssert 和报告能力。

    多显示器支持

    如果您有多个显示器,可以控制特定的显示器:

    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

    下一步