@aiyiran/myclaw 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +9 -57
- package/package.json +1 -1
- package/wsl2.js +392 -0
package/index.js
CHANGED
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
|
|
26
26
|
const { execSync } = require('child_process');
|
|
27
27
|
const os = require('os');
|
|
28
|
+
const path = require('path');
|
|
28
29
|
const { createAgent } = require('./create_agent');
|
|
30
|
+
const { version } = require(path.join(__dirname, 'package.json'));
|
|
29
31
|
|
|
30
32
|
const args = process.argv.slice(2);
|
|
31
33
|
const command = args[0];
|
|
@@ -227,7 +229,6 @@ function runNew() {
|
|
|
227
229
|
console.log('');
|
|
228
230
|
|
|
229
231
|
} catch (err) {
|
|
230
|
-
// create_agent.js 已经有错误信息输出
|
|
231
232
|
console.log('');
|
|
232
233
|
console.log('[' + colors.red + '失败' + colors.nc + '] Agent 创建失败');
|
|
233
234
|
console.log('');
|
|
@@ -236,64 +237,12 @@ function runNew() {
|
|
|
236
237
|
}
|
|
237
238
|
|
|
238
239
|
// ============================================================================
|
|
239
|
-
//
|
|
240
|
+
// WSL2 安装 (独立模块)
|
|
240
241
|
// ============================================================================
|
|
241
242
|
|
|
242
243
|
function runWsl2() {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
process.exit(0);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const bar = '----------------------------------------';
|
|
249
|
-
console.log('');
|
|
250
|
-
console.log('[' + colors.blue + 'MyClaw' + colors.nc + '] ' + colors.blue + '修复/安装 Windows WSL2 环境' + colors.nc);
|
|
251
|
-
console.log(bar);
|
|
252
|
-
console.log('');
|
|
253
|
-
console.log('即将申请管理员权限以启用 Windows WSL2 和 虚拟机平台功能...');
|
|
254
|
-
console.log('这使用的是兼容性最好的"手动打补丁"底层方法,用来解决直接安装失败的问题。');
|
|
255
|
-
console.log('[' + colors.yellow + '注意' + colors.nc + '] 请在稍后弹出的 UAC 授权窗口中选【是】。');
|
|
256
|
-
console.log('');
|
|
257
|
-
|
|
258
|
-
const psCommand = `
|
|
259
|
-
Write-Host "============================";
|
|
260
|
-
Write-Host " MyClaw - WSL2 环境底座修复";
|
|
261
|
-
Write-Host "============================";
|
|
262
|
-
Write-Host "";
|
|
263
|
-
Write-Host "步骤 1/3: 正在启用 Windows Subsystem for Linux...";
|
|
264
|
-
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart;
|
|
265
|
-
Write-Host "";
|
|
266
|
-
Write-Host "步骤 2/3: 正在启用 虚拟机平台...";
|
|
267
|
-
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart;
|
|
268
|
-
Write-Host "";
|
|
269
|
-
Write-Host "步骤 3/3: 尝试设置 WSL2 为默认版本...";
|
|
270
|
-
try { wsl --set-default-version 2 2>$null } catch {}
|
|
271
|
-
Write-Host "";
|
|
272
|
-
Write-Host "============================";
|
|
273
|
-
Write-Host " 操作执行完毕!";
|
|
274
|
-
Write-Host " 注意:必须 [重新启动电脑] 才能生效!";
|
|
275
|
-
Write-Host "============================";
|
|
276
|
-
Write-Host " -> 若重启后运行 wsl 提示需要内核更新,";
|
|
277
|
-
Write-Host " -> 请浏览器访问下载并安装: https://aka.ms/wsl2kernel";
|
|
278
|
-
Write-Host " -> 最后去 Microsoft Store 搜索 Ubuntu 并安装即可。";
|
|
279
|
-
Write-Host "";
|
|
280
|
-
Write-Host "按任意键退出当前窗口...";
|
|
281
|
-
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");
|
|
282
|
-
`;
|
|
283
|
-
|
|
284
|
-
// 为了跨 PowerShell 调用避免引号转移错乱,转为 Base64 执行 (UTF-16LE 编码)
|
|
285
|
-
const b64Cmd = Buffer.from(psCommand, 'utf16le').toString('base64');
|
|
286
|
-
|
|
287
|
-
try {
|
|
288
|
-
execSync(`powershell -Command "Start-Process powershell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -EncodedCommand ${b64Cmd}' -Verb RunAs"`, { stdio: 'inherit' });
|
|
289
|
-
console.log('[' + colors.green + '成功' + colors.nc + '] 修复命令已下发,请查看新弹出的蓝色 PowerShell 窗口。');
|
|
290
|
-
console.log('');
|
|
291
|
-
console.log('执行完后记得 ' + colors.yellow + '重启电脑' + colors.nc + ' 哦!');
|
|
292
|
-
console.log('');
|
|
293
|
-
} catch (err) {
|
|
294
|
-
console.error('[' + colors.red + '错误' + colors.nc + '] 执行提权脚本失败:', err.message);
|
|
295
|
-
console.log('建议右键点击终端,选择【以管理员身份运行】再重试。');
|
|
296
|
-
}
|
|
244
|
+
const wsl2 = require('./wsl2');
|
|
245
|
+
wsl2.run();
|
|
297
246
|
}
|
|
298
247
|
|
|
299
248
|
// ============================================================================
|
|
@@ -312,13 +261,14 @@ function showHelp() {
|
|
|
312
261
|
console.log(' install 安装 OpenClaw 服务');
|
|
313
262
|
console.log(' status 简化版状态查看(学生友好)');
|
|
314
263
|
console.log(' new 创建新的 Agent(学生练习用)');
|
|
315
|
-
console.log(' wsl2
|
|
264
|
+
console.log(' wsl2 WSL2 一键安装/修复 (仅限 Windows)');
|
|
316
265
|
console.log(' help 显示帮助信息');
|
|
317
266
|
console.log('');
|
|
318
267
|
console.log('示例:');
|
|
319
268
|
console.log(' myclaw install # 安装 OpenClaw');
|
|
320
269
|
console.log(' myclaw status # 查看状态');
|
|
321
270
|
console.log(' myclaw new helper # 创建名为 helper 的 Agent');
|
|
271
|
+
console.log(' myclaw wsl2 # Windows 下一键安装 WSL2');
|
|
322
272
|
console.log('');
|
|
323
273
|
console.log('跨平台: macOS / Linux / Windows (PowerShell/CMD)');
|
|
324
274
|
console.log('');
|
|
@@ -328,6 +278,8 @@ function showHelp() {
|
|
|
328
278
|
// 主逻辑
|
|
329
279
|
// ============================================================================
|
|
330
280
|
|
|
281
|
+
console.log(colors.blue + 'MyClaw v' + version + colors.nc);
|
|
282
|
+
|
|
331
283
|
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
332
284
|
showHelp();
|
|
333
285
|
} else if (command === 'install') {
|
package/package.json
CHANGED
package/wsl2.js
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ============================================================================
|
|
5
|
+
* MyClaw WSL2 一键安装器 (终极全自动版)
|
|
6
|
+
* ============================================================================
|
|
7
|
+
*
|
|
8
|
+
* 使用方式: myclaw wsl2
|
|
9
|
+
*
|
|
10
|
+
* 自动检测当前 WSL2 安装状态,分两个阶段完成安装:
|
|
11
|
+
* Phase 1: 启用底层 Windows 功能 + 预下载安装包 → 需要重启
|
|
12
|
+
* Phase 2: 安装内核更新 + Ubuntu → 完成
|
|
13
|
+
*
|
|
14
|
+
* 用户只需反复运行 myclaw wsl2,脚本会自动接续上次的进度。
|
|
15
|
+
* ============================================================================
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const { execSync } = require('child_process');
|
|
19
|
+
const os = require('os');
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// 配置
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
// 下载源(可替换为你自己的 CDN 地址加速国内下载)
|
|
26
|
+
const WSL_CDN = {
|
|
27
|
+
kernel: 'https://cdn.yiranlaoshi.com/software/myclaw/wsl_update_x64.msi',
|
|
28
|
+
// ★ 预制 rootfs tar 包(内含 Node.js + OpenClaw,用户开箱即用)
|
|
29
|
+
// TODO: 替换为你自己的 CDN 地址,制作方法见 README
|
|
30
|
+
rootfs: 'https://openclaw.ai/wsl/openclaw-rootfs.tar',
|
|
31
|
+
// 降级备选:微软官方 Ubuntu Appx 包
|
|
32
|
+
ubuntu: 'https://aka.ms/wslubuntu2204',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ★ 是否启用降级方案(方法 B: wsl --install / 方法 C: Appx 离线包)
|
|
36
|
+
// 如果你的 CDN 稳定可靠,设为 false 只用方法 A(tar 导入)
|
|
37
|
+
const ENABLE_FALLBACK = false;
|
|
38
|
+
|
|
39
|
+
const isWindows = os.platform() === 'win32';
|
|
40
|
+
|
|
41
|
+
// 颜色(Windows 下禁用避免乱码)
|
|
42
|
+
const C = isWindows
|
|
43
|
+
? { r: '', g: '', y: '', b: '', nc: '' }
|
|
44
|
+
: { r: '\x1b[31m', g: '\x1b[32m', y: '\x1b[33m', b: '\x1b[34m', nc: '\x1b[0m' };
|
|
45
|
+
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// 工具函数
|
|
48
|
+
// ============================================================================
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 以管理员权限启动 PowerShell 脚本
|
|
52
|
+
* 利用 UTF-16LE Base64 编码避免引号转义地狱
|
|
53
|
+
*/
|
|
54
|
+
function launchElevatedPS(script) {
|
|
55
|
+
const b64 = Buffer.from(script, 'utf16le').toString('base64');
|
|
56
|
+
try {
|
|
57
|
+
execSync(
|
|
58
|
+
`powershell -Command "Start-Process powershell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -EncodedCommand ${b64}' -Verb RunAs"`,
|
|
59
|
+
{ stdio: 'inherit' }
|
|
60
|
+
);
|
|
61
|
+
return true;
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.error('[' + C.r + '错误' + C.nc + '] 无法获取管理员权限: ' + err.message);
|
|
64
|
+
console.log('建议右键终端选择【以管理员身份运行】后重试。');
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// 状态检测
|
|
71
|
+
// ============================================================================
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 自动检测当前 WSL2 安装状态
|
|
75
|
+
* @returns {'ready'|'needs-setup'|'needs-features'}
|
|
76
|
+
*/
|
|
77
|
+
function detectState() {
|
|
78
|
+
// 1. WSL 已完全可用(有发行版能跑命令)
|
|
79
|
+
try {
|
|
80
|
+
execSync('wsl echo ok', { stdio: 'pipe', timeout: 15000 });
|
|
81
|
+
return 'ready';
|
|
82
|
+
} catch {}
|
|
83
|
+
|
|
84
|
+
// 2. WSL 命令可用但没有发行版(功能已启用,重启后的状态)
|
|
85
|
+
try {
|
|
86
|
+
execSync('wsl --status', { stdio: 'pipe', timeout: 5000 });
|
|
87
|
+
return 'needs-setup';
|
|
88
|
+
} catch {}
|
|
89
|
+
|
|
90
|
+
// 3. WSL 功能未启用
|
|
91
|
+
return 'needs-features';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// Phase 1: 启用底层功能 + 预下载
|
|
96
|
+
// ============================================================================
|
|
97
|
+
|
|
98
|
+
function runPhase1() {
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log('[当前进度] WSL 功能 ' + C.r + '[未启用]' + C.nc);
|
|
101
|
+
console.log(' 内核更新 ' + C.r + '[未安装]' + C.nc);
|
|
102
|
+
console.log(' Ubuntu ' + C.r + '[未安装]' + C.nc);
|
|
103
|
+
console.log('');
|
|
104
|
+
console.log('本次执行 阶段 1/2: 启用底层功能 + 预下载安装包');
|
|
105
|
+
console.log(' 完成后需要 ' + C.y + '重启电脑' + C.nc);
|
|
106
|
+
console.log(' 重启后再运行 ' + C.y + 'myclaw wsl2' + C.nc + ' 自动进入阶段 2');
|
|
107
|
+
console.log('');
|
|
108
|
+
console.log('[' + C.y + '注意' + C.nc + '] 请在 UAC 弹窗中点击【是】');
|
|
109
|
+
console.log('');
|
|
110
|
+
|
|
111
|
+
const ps = `
|
|
112
|
+
$ErrorActionPreference = 'Continue'
|
|
113
|
+
$Host.UI.RawUI.WindowTitle = 'MyClaw WSL2 Installer - Phase 1'
|
|
114
|
+
Write-Host ''
|
|
115
|
+
Write-Host '========================================'
|
|
116
|
+
Write-Host ' MyClaw WSL2 安装 - 阶段 1/2'
|
|
117
|
+
Write-Host ' 启用底层功能 + 预下载安装包'
|
|
118
|
+
Write-Host '========================================'
|
|
119
|
+
Write-Host ''
|
|
120
|
+
|
|
121
|
+
Write-Host '[1/4] 启用 Windows Subsystem for Linux...'
|
|
122
|
+
try {
|
|
123
|
+
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart | Out-Null
|
|
124
|
+
Write-Host ' [OK]'
|
|
125
|
+
} catch {
|
|
126
|
+
Write-Host ' 跳过 (可能已启用)'
|
|
127
|
+
}
|
|
128
|
+
Write-Host ''
|
|
129
|
+
|
|
130
|
+
Write-Host '[2/4] 启用虚拟机平台 (VirtualMachinePlatform)...'
|
|
131
|
+
try {
|
|
132
|
+
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart | Out-Null
|
|
133
|
+
Write-Host ' [OK]'
|
|
134
|
+
} catch {
|
|
135
|
+
Write-Host ' 跳过 (可能已启用)'
|
|
136
|
+
}
|
|
137
|
+
Write-Host ''
|
|
138
|
+
|
|
139
|
+
Write-Host '[3/4] 预下载 WSL2 内核更新包...'
|
|
140
|
+
$dir = "$env:LOCALAPPDATA\\myclaw"
|
|
141
|
+
$msi = "$dir\\wsl_update_x64.msi"
|
|
142
|
+
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
143
|
+
try {
|
|
144
|
+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
145
|
+
Invoke-WebRequest -Uri '${WSL_CDN.kernel}' -OutFile $msi -UseBasicParsing
|
|
146
|
+
Write-Host ' [OK] 已缓存'
|
|
147
|
+
} catch {
|
|
148
|
+
Write-Host ' [跳过] 下载失败, 重启后将重试'
|
|
149
|
+
}
|
|
150
|
+
Write-Host ''
|
|
151
|
+
|
|
152
|
+
Write-Host '[4/4] 尝试提前安装内核更新...'
|
|
153
|
+
if (Test-Path $msi) {
|
|
154
|
+
try {
|
|
155
|
+
Start-Process msiexec.exe -ArgumentList "/i \`"$msi\`" /quiet /norestart" -Wait -NoNewWindow
|
|
156
|
+
Write-Host ' [OK]'
|
|
157
|
+
} catch {
|
|
158
|
+
Write-Host ' [跳过] 重启后将自动完成'
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
Write-Host ' [跳过] 文件未就绪'
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
Write-Host ''
|
|
165
|
+
Write-Host '========================================'
|
|
166
|
+
Write-Host ' 阶段 1/2 完成!'
|
|
167
|
+
Write-Host ''
|
|
168
|
+
Write-Host ' >>> 请立即 [重启电脑] <<<'
|
|
169
|
+
Write-Host ''
|
|
170
|
+
Write-Host ' 重启后运行: myclaw wsl2'
|
|
171
|
+
Write-Host ' 将自动进入阶段 2 完成安装'
|
|
172
|
+
Write-Host '========================================'
|
|
173
|
+
Write-Host ''
|
|
174
|
+
Write-Host '按任意键关闭此窗口...'
|
|
175
|
+
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
|
176
|
+
`;
|
|
177
|
+
|
|
178
|
+
if (launchElevatedPS(ps)) {
|
|
179
|
+
console.log('[' + C.g + '已启动' + C.nc + '] 请查看新弹出的蓝色窗口');
|
|
180
|
+
console.log('');
|
|
181
|
+
console.log('执行完请 ' + C.y + '重启电脑' + C.nc + ',然后运行 ' + C.y + 'myclaw wsl2' + C.nc + ' 续装');
|
|
182
|
+
console.log('');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ============================================================================
|
|
187
|
+
// Phase 2: 安装内核 + Ubuntu
|
|
188
|
+
// ============================================================================
|
|
189
|
+
|
|
190
|
+
function runPhase2() {
|
|
191
|
+
console.log('');
|
|
192
|
+
console.log('[当前进度] WSL 功能已启用 ' + C.g + '[OK]' + C.nc);
|
|
193
|
+
console.log(' 内核更新 + Ubuntu ' + C.y + '[待安装]' + C.nc);
|
|
194
|
+
console.log('');
|
|
195
|
+
console.log('即将自动下载并安装(需要管理员权限)...');
|
|
196
|
+
console.log('[' + C.y + '注意' + C.nc + '] 请在 UAC 弹窗中点击【是】');
|
|
197
|
+
console.log('');
|
|
198
|
+
|
|
199
|
+
const ps = `
|
|
200
|
+
$ErrorActionPreference = 'Continue'
|
|
201
|
+
$Host.UI.RawUI.WindowTitle = 'MyClaw WSL2 Installer - Phase 2'
|
|
202
|
+
Write-Host ''
|
|
203
|
+
Write-Host '========================================'
|
|
204
|
+
Write-Host ' MyClaw WSL2 安装 - 阶段 2/2'
|
|
205
|
+
Write-Host ' 安装内核更新 + Ubuntu'
|
|
206
|
+
Write-Host '========================================'
|
|
207
|
+
Write-Host ''
|
|
208
|
+
|
|
209
|
+
Write-Host '[1/5] 设置 WSL2 为默认版本...'
|
|
210
|
+
try { wsl --set-default-version 2 2>$null } catch {}
|
|
211
|
+
Write-Host ' [OK]'
|
|
212
|
+
Write-Host ''
|
|
213
|
+
|
|
214
|
+
Write-Host '[2/5] 安装 WSL2 内核更新包...'
|
|
215
|
+
$dir = "$env:LOCALAPPDATA\\myclaw"
|
|
216
|
+
$msi = "$dir\\wsl_update_x64.msi"
|
|
217
|
+
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
218
|
+
|
|
219
|
+
if (-Not (Test-Path $msi)) {
|
|
220
|
+
Write-Host ' 正在从微软服务器下载...'
|
|
221
|
+
try {
|
|
222
|
+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
223
|
+
Invoke-WebRequest -Uri '${WSL_CDN.kernel}' -OutFile $msi -UseBasicParsing
|
|
224
|
+
Write-Host ' 下载完成!'
|
|
225
|
+
} catch {
|
|
226
|
+
Write-Host ' [失败] 下载失败,请检查网络'
|
|
227
|
+
Write-Host ' 手动下载: https://aka.ms/wsl2kernel'
|
|
228
|
+
Write-Host ''; Write-Host '按任意键退出...'
|
|
229
|
+
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
|
230
|
+
exit 1
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
Write-Host ' 使用上次预下载的缓存文件'
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
Start-Process msiexec.exe -ArgumentList "/i \`"$msi\`" /quiet /norestart" -Wait -NoNewWindow
|
|
237
|
+
Write-Host ' [OK] 内核更新安装成功!'
|
|
238
|
+
} catch {
|
|
239
|
+
Write-Host ' 可能已安装,继续...'
|
|
240
|
+
}
|
|
241
|
+
Write-Host ''
|
|
242
|
+
|
|
243
|
+
Write-Host '[3/5] 确认 WSL2 为默认版本...'
|
|
244
|
+
try { wsl --set-default-version 2 2>$null } catch {}
|
|
245
|
+
Write-Host ' [OK]'
|
|
246
|
+
Write-Host ''
|
|
247
|
+
|
|
248
|
+
Write-Host '[4/5] 安装 Linux 发行版...'
|
|
249
|
+
$installed = $false
|
|
250
|
+
$distroName = 'OpenClaw'
|
|
251
|
+
$installDir = "$dir\\OpenClaw"
|
|
252
|
+
|
|
253
|
+
# ---- 方法 A (最强): 预制 rootfs tar 包,wsl --import ----
|
|
254
|
+
Write-Host ' 方法 A: 导入 OpenClaw 预制 Linux 环境...'
|
|
255
|
+
$tarPath = "$dir\\openclaw-rootfs.tar"
|
|
256
|
+
if (-Not (Test-Path $tarPath)) {
|
|
257
|
+
Write-Host ' 正在下载预制环境包...'
|
|
258
|
+
try {
|
|
259
|
+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
260
|
+
Invoke-WebRequest -Uri '` + WSL_CDN.rootfs + `' -OutFile $tarPath -UseBasicParsing
|
|
261
|
+
Write-Host ' 下载完成!'
|
|
262
|
+
} catch {
|
|
263
|
+
Write-Host ' 下载失败, 尝试备选方案...'
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (Test-Path $tarPath) {
|
|
267
|
+
try {
|
|
268
|
+
New-Item -ItemType Directory -Force -Path $installDir | Out-Null
|
|
269
|
+
wsl --import $distroName $installDir $tarPath 2>$null
|
|
270
|
+
if ($LASTEXITCODE -eq 0) {
|
|
271
|
+
$installed = $true
|
|
272
|
+
Write-Host ' [OK] 方法 A 成功! (预制环境已导入)'
|
|
273
|
+
}
|
|
274
|
+
} catch {}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
# ---- 方法 B / C (降级备选,由 ENABLE_FALLBACK 控制) ----
|
|
278
|
+
` + (ENABLE_FALLBACK ? `
|
|
279
|
+
if (-Not $installed) {
|
|
280
|
+
Write-Host ' 方法 B: wsl --install ...'
|
|
281
|
+
try {
|
|
282
|
+
$output = wsl --install -d Ubuntu --no-launch 2>&1
|
|
283
|
+
if ($LASTEXITCODE -eq 0) {
|
|
284
|
+
$installed = $true
|
|
285
|
+
Write-Host ' [OK] 方法 B 成功!'
|
|
286
|
+
}
|
|
287
|
+
} catch {}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (-Not $installed) {
|
|
291
|
+
Write-Host ' 方法 C: 离线 Appx 安装...'
|
|
292
|
+
$appx = "$dir\\Ubuntu.appx"
|
|
293
|
+
if (-Not (Test-Path $appx)) {
|
|
294
|
+
Write-Host ' 正在下载 Ubuntu (约 500MB)...'
|
|
295
|
+
try {
|
|
296
|
+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
297
|
+
Invoke-WebRequest -Uri '` + WSL_CDN.ubuntu + `' -OutFile $appx -UseBasicParsing
|
|
298
|
+
} catch {
|
|
299
|
+
Write-Host ' [失败] 下载失败'
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (Test-Path $appx) {
|
|
303
|
+
try {
|
|
304
|
+
Add-AppxPackage -Path $appx
|
|
305
|
+
$installed = $true
|
|
306
|
+
Write-Host ' [OK] 方法 C 成功!'
|
|
307
|
+
} catch {}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
` : `
|
|
311
|
+
if (-Not $installed) {
|
|
312
|
+
Write-Host ' [失败] 预制环境包安装失败'
|
|
313
|
+
Write-Host ' 请检查网络后重试: myclaw wsl2'
|
|
314
|
+
}
|
|
315
|
+
`) + `
|
|
316
|
+
Write-Host ''
|
|
317
|
+
|
|
318
|
+
Write-Host '[5/5] 验证安装结果...'
|
|
319
|
+
try {
|
|
320
|
+
$result = wsl -l -v 2>&1 | Out-String
|
|
321
|
+
Write-Host $result
|
|
322
|
+
} catch {
|
|
323
|
+
Write-Host ' 无法获取信息'
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
Write-Host ''
|
|
327
|
+
Write-Host '========================================'
|
|
328
|
+
if ($installed) {
|
|
329
|
+
Write-Host ' [OK] WSL2 + Linux 环境安装完成!'
|
|
330
|
+
Write-Host ''
|
|
331
|
+
Write-Host ' 输入 wsl 即可进入 Linux 环境'
|
|
332
|
+
Write-Host ' 如使用预制包, OpenClaw 已预装就绪'
|
|
333
|
+
} else {
|
|
334
|
+
Write-Host ' [注意] Linux 发行版可能需要手动安装'
|
|
335
|
+
Write-Host ' 请打开 Microsoft Store 搜索 Ubuntu'
|
|
336
|
+
}
|
|
337
|
+
Write-Host '========================================'
|
|
338
|
+
Write-Host ''
|
|
339
|
+
Write-Host '按任意键关闭此窗口...'
|
|
340
|
+
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
|
341
|
+
`;
|
|
342
|
+
|
|
343
|
+
if (launchElevatedPS(ps)) {
|
|
344
|
+
console.log('[' + C.g + '已启动' + C.nc + '] 请查看新弹出的蓝色窗口');
|
|
345
|
+
console.log('');
|
|
346
|
+
console.log('安装完成后,输入 ' + C.y + 'wsl' + C.nc + ' 即可进入 Linux');
|
|
347
|
+
console.log('可随时运行 ' + C.y + 'myclaw wsl2' + C.nc + ' 检查状态');
|
|
348
|
+
console.log('');
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ============================================================================
|
|
353
|
+
// 主入口
|
|
354
|
+
// ============================================================================
|
|
355
|
+
|
|
356
|
+
function run() {
|
|
357
|
+
if (!isWindows) {
|
|
358
|
+
console.error('[提示] 本命令仅用于 Windows 系统。Mac/Linux 不需要 WSL2。');
|
|
359
|
+
process.exit(0);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const bar = '========================================';
|
|
363
|
+
const state = detectState();
|
|
364
|
+
|
|
365
|
+
console.log('');
|
|
366
|
+
console.log('[' + C.b + 'MyClaw' + C.nc + '] WSL2 一键安装向导');
|
|
367
|
+
console.log(bar);
|
|
368
|
+
|
|
369
|
+
if (state === 'ready') {
|
|
370
|
+
console.log('');
|
|
371
|
+
console.log('[' + C.g + 'OK' + C.nc + '] WSL2 已完全安装就绪!');
|
|
372
|
+
console.log('');
|
|
373
|
+
try {
|
|
374
|
+
const info = execSync('wsl -l -v', { stdio: 'pipe' }).toString('utf16le');
|
|
375
|
+
console.log(info.trim());
|
|
376
|
+
} catch {
|
|
377
|
+
console.log('(运行 wsl -l -v 查看详情)');
|
|
378
|
+
}
|
|
379
|
+
console.log('');
|
|
380
|
+
console.log('输入 ' + C.y + 'wsl' + C.nc + ' 即可进入 Linux 环境。');
|
|
381
|
+
console.log('');
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (state === 'needs-setup') {
|
|
386
|
+
runPhase2();
|
|
387
|
+
} else {
|
|
388
|
+
runPhase1();
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
module.exports = { run };
|