整体框架架构
OpenClaw Desktop 采用经典的 Electron 主进程与渲染进程分离架构
主进程
管理 Electron 应用生命周期,创建主窗口,处理系统级操作, 通过 IPC 与渲染进程通信,调用 OpenClaw CLI 命令。
预加载脚本
安全的上下文隔离桥接层,使用 contextBridge 暴露安全的 API, 防止渲染进程直接访问 Node.js API。
渲染进程
现代 Web 技术构建的用户界面,包含仪表盘、聊天、设置、日志、 安装指南等多个功能页面。
desktop-app/
├── main.js # Electron 主进程入口
├── preload.js # 预加载脚本 (IPC 桥接)
├── chat-handler.js # OpenClaw 聊天处理器
├── package.json # 项目配置和依赖
├── public/ # 前端资源
│ ├── index.html # 主页面
│ ├── styles.css # 样式文件
│ └── app.js # 前端逻辑
├── src/ # 源代码
│ ├── services/ # 服务模块
│ │ └── gateway-service.js # Gateway 服务管理
│ └── config/ # 配置模块
│ └── openclaw-config.js # OpenClaw 配置管理
└── dist/ # 打包输出目录
项目依赖详解
完整的 npm 依赖清单及其作用说明
{
"name": "openclaw-desktop",
"version": "1.0.0",
"description": "OpenClaw Desktop Application",
"main": "main.js", // Electron 入口文件
// ========== 运行时依赖 ==========
"dependencies": {
"axios": "^1.6.0", // HTTP 客户端,用于 API 调用
"electron-store": "^8.1.0", // 持久化存储配置
"openclaw": "^2026.3.8" // OpenClaw CLI 核心包
},
// ========== 开发依赖 ==========
"devDependencies": {
"electron": "^28.0.0", // Electron 框架核心
"electron-builder": "^24.9.0" // 打包构建工具
},
// ========== 构建配置 ==========
"build": {
"appId": "com.openclaw.desktop",
"productName": "OpenClaw Desktop",
"win": {
"target": ["portable"], // Windows 便携版
"signingHashAlgorithms": [] // 跳过代码签名
}
}
}
依赖详细说明
| 依赖包 | 版本 | 类型 | 作用说明 |
|---|---|---|---|
electron |
^28.0.0 | 开发依赖 | 跨平台桌面应用框架,提供 Chromium + Node.js 运行环境 |
electron-builder |
^24.9.0 | 开发依赖 | 将 Electron 应用打包成可执行文件和安装包 |
electron-store |
^8.1.0 | 运行时依赖 | 简单的键值对存储,用于持久化用户配置 |
axios |
^1.6.0 | 运行时依赖 | HTTP 客户端,用于与 OpenClaw Gateway API 通信 |
openclaw |
^2026.3.8 | 运行时依赖 | OpenClaw CLI 核心包,提供所有 AI Agent 功能 |
rm -rf node_modules package-lock.json && npm install
OpenClaw 集成详解
如何通过 Electron 调用 OpenClaw CLI 命令
核心命令集成
// 在 main.js 中处理 IPC 调用
const { spawn } = require('child_process');
// 启动 Gateway 服务
ipcMain.handle('gateway-start', async () => {
const command = 'openclaw';
const args = ['gateway', 'run', '--port', '18789'];
// 使用 spawn 启动子进程
const child = spawn(command, args, {
shell: true, // Windows 需要 shell 模式
detached: true, // 让子进程独立运行
stdio: ['ignore', 'pipe', 'pipe'] // 捕获输出
});
return { success: true, pid: child.pid };
});
// chat-handler.js - 聊天处理器核心代码
class ChatHandler {
sendMessage(message, model = 'zai/glm-4.7') {
return new Promise((resolve, reject) => {
// 构建 OpenClaw agent 命令
const args = [
'agent', // 使用 agent 子命令
'--agent', 'main', // 指定使用 main 代理
'--local', // 本地运行模式
'--message', message,// 用户消息
'--json' // JSON 格式输出
];
// Windows 使用 npx.cmd,Unix 使用 npx
const command = process.platform === 'win32' ? 'npx.cmd' : 'npx';
// 关键:不使用 shell 模式,避免参数解析问题
const child = spawn(command, ['openclaw', ...args], {
env: { ...process.env },
stdio: ['ignore', 'pipe', 'pipe'],
shell: false // 明确禁用 shell
});
// 处理输出和错误...
});
}
}
shell: true 会导致 shell
错误地将消息解析成多个参数。解决方案是:1. 使用
shell: false2. 将消息作为独立的数组元素传递
3. Windows 使用
npx.cmd 而不是 npx
常用 OpenClaw 命令
# ========== Gateway 服务管理 ==========
openclaw gateway run # 启动 Gateway (默认端口 18789)
openclaw gateway run --port 19001 # 指定端口启动
openclaw gateway run --force # 强制启动 (杀死占用端口的进程)
# ========== Agent 交互 ==========
openclaw agent --agent main --local --message "Hello" --json
# 发送消息给本地代理
# ========== 配置管理 ==========
openclaw config file # 显示配置文件路径
openclaw config get agents.defaults.model.primary # 获取配置
openclaw config set agents.defaults.model.primary zai/glm-4.6 # 设置配置
# ========== 状态查询 ==========
openclaw health # 检查 Gateway 健康状态
openclaw status # 查看通道状态
openclaw models list # 列出可用模型
openclaw agents list # 列出可用代理
# ========== Dashboard ==========
openclaw dashboard # 在浏览器中打开 Dashboard
openclaw tui # 打开终端界面 (TUI)
OpenClaw 安装配置指南
完整的 OpenClaw 安装、配置和启动教程
- ✅ 环境准备 - Node.js、命令行工具、网络要求
- ✅ 安装 OpenClaw - npm 全局安装和验证
- ✅ 运行配置向导 - 交互式配置流程说明
- ✅ 配置 API Key - 智谱 AI API Key 获取指南
- ✅ 启动 Gateway - 多种启动方式和后台运行
- ✅ 访问 Dashboard - Web 界面和 TUI 使用方法
- ✅ 常用管理命令 - 健康检查、状态查看、日志管理
- ✅ 故障排除 - 常见问题和解决方案
快速安装
一行命令完成安装:
npm install -g openclaw
配置向导
运行交互式配置:
openclaw configure
启动服务
启动 Gateway 服务:
openclaw gateway run
核心代码深度讲解
关键模块的实现细节和最佳实践
// preload.js - 主进程和渲染进程之间的安全桥接
const { contextBridge, ipcRenderer } = require('electron');
// ========== 使用 contextBridge 安全地暴露 API ==========
contextBridge.exposeInMainWorld('electronAPI', {
// ========== Gateway 服务管理 ==========
gateway: {
start: () => ipcRenderer.invoke('gateway-start'),
stop: () => ipcRenderer.invoke('gateway-stop'),
getStatus: () => ipcRenderer.invoke('gateway-status')
},
// ========== 配置管理 ==========
config: {
get: (key) => ipcRenderer.invoke('config-get', key),
set: (key, value) => ipcRenderer.invoke('config-set', key, value),
getFile: () => ipcRenderer.invoke('config-file')
},
// ========== 聊天功能 ==========
chat: {
send: (message, options) =>
ipcRenderer.invoke('chat-send', message, options)
},
// ========== 系统信息 ==========
system: {
getAppInfo: () => ipcRenderer.invoke('system-info'),
getInitStatus: () => ipcRenderer.invoke('init-status'),
openPath: (path) => ipcRenderer.invoke('open-path', path)
}
});
// ========== 渲染进程中的使用方式 ==========
// window.electronAPI.gateway.start()
// window.electronAPI.chat.send("Hello")
// main.js - Electron 主进程入口
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const ChatHandler = require('./chat-handler');
// ========== 全局变量 ==========
let mainWindow;
let gatewayProcess = null;
// ========== 创建主窗口 ==========
function createWindow() {
mainWindow = new BrowserWindow({
width: 1400,
height: 900,
minWidth: 1200,
minHeight: 700,
webPreferences: {
nodeIntegration: false, // 禁用 Node.js 集成 (安全)
contextIsolation: true, // 启用上下文隔离 (安全)
preload: path.join(__dirname, 'preload.js') // 预加载脚本
},
titleBarStyle: 'hidden', // 隐藏默认标题栏
backgroundColor: '#0d0d0d' // 暗色主题背景
});
// 加载主页面
mainWindow.loadFile(path.join(__dirname, 'public/index.html'));
// 开发模式下打开 DevTools
if (process.argv.includes('--dev')) {
mainWindow.webContents.openDevTools();
}
}
// ========== IPC 事件处理器 ==========
// 启动 Gateway
ipcMain.handle('gateway-start', async () => {
if (gatewayProcess) {
return { success: false, error: 'Gateway already running' };
}
const { spawn } = require('child_process');
gatewayProcess = spawn('openclaw', ['gateway', 'run'], {
shell: true,
detached: true
});
return { success: true, pid: gatewayProcess.pid };
});
// 停止 Gateway
ipcMain.handle('gateway-stop', async () => {
if (gatewayProcess) {
process.kill(gatewayProcess.pid);
gatewayProcess = null;
}
return { success: true };
});
// 发送聊天消息
ipcMain.handle('chat-send', async (event, message, options = {}) => {
try {
const chatHandler = new ChatHandler(options.port || 18789);
const result = await chatHandler.sendMessage(message, options.model);
return result;
} catch (error) {
return { success: false, error: error.message };
}
});
// ========== 应用生命周期 ==========
app.whenReady().then(() => {
createWindow();
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
2. nodeIntegration: false - 禁用 Node.js 集成,减少安全风险
3. contextBridge.exposeInMainWorld - 安全地暴露特定的 API 给渲染进程
4. shell: false - 在 spawn 中避免 shell 解析问题
完整开发步骤
从零开始构建 OpenClaw Desktop 应用
-
步骤 1: 创建项目结构
创建桌面应用目录,初始化 npm 项目,设置基本目录结构
-
步骤 2: 安装依赖
安装 Electron、electron-builder、openclaw 等核心依赖
-
步骤 3: 创建主进程
实现 main.js,创建窗口,设置 IPC 处理器
-
步骤 4: 创建预加载脚本
实现 preload.js,安全地暴露 API 给渲染进程
-
步骤 5: 创建用户界面
设计并实现 index.html、styles.css 和 app.js
-
步骤 6: 实现 OpenClaw 集成
创建 chat-handler.js,实现与 OpenClaw CLI 的交互
-
步骤 7: 测试与调试
运行 npm start 测试应用,使用 DevTools 调试
-
步骤 8: 打包发布
使用 electron-builder 打包成 Windows 便携版 EXE
# ========== 1. 创建项目 ==========
mkdir openclaw-desktop && cd openclaw-desktop
npm init -y
# ========== 2. 安装依赖 ==========
npm install --save-dev electron@^28.0.0 electron-builder@^24.9.0
npm install axios electron-store openclaw
# ========== 3. 运行开发模式 ==========
npm start
# ========== 4. 打包应用 ==========
npm run build
# 打包完成后,在 dist 目录找到生成的 EXE 文件
npm start -- --dev 启动应用并自动打开 DevTools。
所有修改保存后需要按 Ctrl+R 重新加载窗口来查看效果。