子进程集成方案(推荐)
作为独立进程运行
// main.js
const { app, BrowserWindow } = require('electron')
const { spawn } = require('child_process')
const path = require('path')
let openClawProcess
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
})
win.loadFile('index.html')
}
// 启动 OpenClaw
function startOpenClaw() {
const openClawPath = path.join(__dirname, 'openclaw', 'claw.exe') // Windows
// const openClawPath = path.join(__dirname, 'openclaw', 'claw') // Linux/macOS
openClawProcess = spawn(openClawPath, [
'--rom', 'path/to/rom',
'--config', 'path/to/config'
])
// 处理进程通信
openClawProcess.stdout.on('data', (data) => {
console.log(`OpenClaw: ${data}`)
})
openClawProcess.stderr.on('data', (data) => {
console.error(`OpenClaw Error: ${data}`)
})
openClawProcess.on('close', (code) => {
console.log(`OpenClaw exited with code ${code}`)
})
}
app.whenReady().then(() => {
createWindow()
startOpenClaw()
})
进程间通信(IPC)
// main.js - 主进程
const { ipcMain } = require('electron')
ipcMain.handle('openclaw-control', async (event, command, args) => {
switch(command) {
case 'start':
// 启动 OpenClaw
break
case 'pause':
// 发送暂停命令
openClawProcess.stdin.write('pause\n')
break
case 'load-replay':
// 加载回放文件
break
}
})
// renderer.js - 渲染进程
const { ipcRenderer } = require('electron')
async function controlOpenClaw() {
const result = await ipcRenderer.invoke('openclaw-control', 'start', {
rom: 'game.rom',
replay: 'replay.rpy'
})
}
集成方法比较
独立窗口模式
const { BrowserWindow } = require('electron')
function createOpenClawWindow() {
const openClawWin = new BrowserWindow({
width: 800,
height: 600,
parent: mainWindow,
webPreferences: {
nodeIntegration: true
}
})
// OpenClaw 有 Web 版本
openClawWin.loadURL('http://localhost:8080/openclaw')
// 或者嵌入本地 HTML
openClawWin.loadFile('openclaw-web/index.html')
}
WebView 嵌入
<!-- index.html -->
<webview
id="openclaw-view"
src="http://localhost:8080/openclaw"
style="width: 100%; height: 600px"
allowpopups
nodeintegration
></webview>
<script>
const webview = document.getElementById('openclaw-view')
webview.addEventListener('dom-ready', () => {
// WebView 加载完成
})
</script>
完整的集成架构
项目结构
electron-app/
├── main.js
├── package.json
├── preload.js
├── src/
│ ├── renderer/
│ │ ├── index.html
│ │ └── renderer.js
│ ├── openclaw/
│ │ ├── bin/ # OpenClaw 可执行文件
│ │ ├── config/
│ │ └── data/
│ └── api/
│ └── openclaw-api.js
封装 OpenClaw 控制器
// openclaw-api.js
class OpenClawController {
constructor() {
this.process = null
this.config = {
executable: 'openclaw/bin/claw',
args: [],
env: { ...process.env }
}
}
async start(options = {}) {
const { spawn } = require('child_process')
const path = require('path')
const args = [
'--fullscreen', options.fullscreen || false,
'--speed', options.speed || 1.0
]
if (options.rom) args.push('--rom', options.rom)
if (options.replay) args.push('--replay', options.replay)
this.process = spawn(
path.resolve(__dirname, this.config.executable),
args,
{
stdio: ['pipe', 'pipe', 'pipe'],
env: this.config.env
}
)
return new Promise((resolve, reject) => {
this.process.on('spawn', () => resolve(this.process.pid))
this.process.on('error', reject)
})
}
sendCommand(command) {
if (this.process && this.process.stdin.writable) {
this.process.stdin.write(command + '\n')
}
}
async stop() {
if (this.process) {
this.process.kill('SIGTERM')
await new Promise(resolve => this.process.on('close', resolve))
this.process = null
}
}
}
module.exports = OpenClawController
优化建议
打包资源
// 在 package.json 中配置
{
"build": {
"extraResources": [
{
"from": "openclaw/",
"to": "openclaw/",
"filter": ["**/*"]
}
]
}
}
使用 WebSocket 通信
// WebSocket 服务器(如果需要双向通信)
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 8080 })
wss.on('connection', (ws) => {
ws.on('message', (message) => {
// 转发消息到 OpenClaw 进程
if (openClawProcess) {
openClawProcess.stdin.write(message)
}
})
})
错误处理
process.on('uncaughtException', (error) => {
console.error('OpenClaw error:', error)
// 重启或显示错误界面
})
注意事项
- 平台兼容性:OpenClaw 在不同平台的二进制文件需要分别处理
- 性能考虑:游戏模拟器需要较多 CPU 资源,合理分配进程优先级
- 安全隔离:使用
contextIsolation和preload脚本保护主进程 - 许可证兼容:确保 OpenClaw 的许可证与你的项目兼容
这种集成方式保持了 OpenClaw 的独立性,同时允许 Electron 应用控制和管理游戏回放功能。

版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。