-
-
Notifications
You must be signed in to change notification settings - Fork 69.6k
WSL2: Control Windows browsers (Edge, Chrome) from OpenClaw #16649
Copy link
Copy link
Closed as not planned
Labels
staleMarked as stale due to inactivityMarked as stale due to inactivity
Description
WSL2: Control Windows browsers (Edge, Chrome) from OpenClaw
Enable OpenClaw in WSL2 to auto-spawn and control Windows browsers (Edge, Chrome, Vivaldi) via CDP.
Proposed Config
{
"browser": {
"wsl2": {
"enabled": true,
"autoStart": true,
"browsers": [
"/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe",
"/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
],
"cdpPort": 9223,
"userDataDir": "C:\\Users\\{username}\\AppData\\Local\\OpenClaw\\browser-profile"
}
}
}Implementation
1. WSL2 Detection (src/browser/wsl2.ts - new file)
import { execSync } from 'child_process';
import { existsSync } from 'fs';
import { spawn } from 'child_process';
export function isWSL2(): boolean {
try {
const release = execSync('uname -r', { encoding: 'utf-8' });
return release.toLowerCase().includes('microsoft');
} catch {
return false;
}
}
const BROWSER_PATHS = [
'/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe',
'/mnt/c/Program Files/Microsoft/Edge/Application/msedge.exe',
'/mnt/c/Program Files/Google/Chrome/Application/chrome.exe',
'/mnt/c/Program Files/Vivaldi/Application/vivaldi.exe',
];
export function findWindowsBrowser(): string | null {
return BROWSER_PATHS.find(path => existsSync(path)) || null;
}
export function spawnWindowsBrowser(
browserPath: string,
cdpPort: number,
userDataDir: string
): Promise<void> {
return new Promise((resolve, reject) => {
const args = [
`--remote-debugging-port=${cdpPort}`,
`--user-data-dir=${userDataDir}`,
'--no-first-run',
'--remote-allow-origins=*'
];
const proc = spawn(browserPath, args, { detached: true, stdio: 'ignore' });
proc.on('error', reject);
proc.unref();
// Wait for CDP
const checkReady = (attempts = 0) => {
fetch(`http://localhost:${cdpPort}/json/version`)
.then(() => resolve())
.catch(() => attempts < 10
? setTimeout(() => checkReady(attempts + 1), 500)
: reject(new Error('CDP timeout'))
);
};
setTimeout(() => checkReady(), 500);
});
}2. Browser Service Integration (src/browser/service.ts - modify)
import { isWSL2, findWindowsBrowser, spawnWindowsBrowser } from './wsl2.js';
async function ensureBrowserRunning(profile: BrowserProfile) {
const config = loadConfig();
if (config.browser?.wsl2?.enabled && isWSL2()) {
const isReachable = await isCdpReachable(profile.cdpUrl);
if (!isReachable && config.browser.wsl2.autoStart) {
const browserPath = config.browser.wsl2.browsers?.[0] || findWindowsBrowser();
if (!browserPath) throw new Error('No Windows browser found');
await spawnWindowsBrowser(
browserPath,
config.browser.wsl2.cdpPort || 9223,
config.browser.wsl2.userDataDir ||
`C:\\Users\\${process.env.USER}\\AppData\\Local\\OpenClaw\\browser-profile`
);
}
}
}3. Config Schema (src/browser/config.ts - modify)
interface BrowserConfig {
// ... existing fields
wsl2?: {
enabled: boolean;
autoStart?: boolean;
browsers?: string[];
cdpPort?: number;
userDataDir?: string;
};
}Files Changed
| File | Action |
|---|---|
src/browser/wsl2.ts |
Create - WSL2 detection + browser spawn |
src/browser/config.ts |
Modify - Add wsl2 config schema |
src/browser/service.ts |
Modify - Add ensureBrowserRunning() call |
docs/platforms/windows.md |
Update - Document WSL2 setup |
Testing
# WSL2 environment
openclaw browser open "https://example.com"
# → Should auto-spawn Edge/Chrome and open URL
openclaw browser snapshot --mode role
# → Should return accessibility treeTested: OpenClaw v2026.2.13, WSL2 Ubuntu 22.04 + Windows 11, Edge 144.x
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
staleMarked as stale due to inactivityMarked as stale due to inactivity
Type
Fields
Give feedbackNo fields configured for issues without a type.