# Bookworm Portable 启动器 bat 生成工具 (v3.0.6) # 用途: 从单一明文 PowerShell 脚本生成两个 bat, 避免手工同步 Base64 字符串不一致 # 用法: pwsh -NoProfile -File tools/gen-launcher-bats.ps1 # 输出: 启动Bookworm.bat + 更新并启动Bookworm.bat (覆盖写入) $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent $PSScriptRoot $launchBat = Join-Path $repoRoot "启动Bookworm.bat" $updateBat = Join-Path $repoRoot "更新并启动Bookworm.bat" # ─── 明文: DPAPI 加载 + PATH 重载 + claude 诊断 + 启动 ───────── $plainScript = @' Add-Type -AssemblyName System.Security $env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User') $r = 'HKCU:\Software\Bookworm\CachedEnv' try { (Get-ItemProperty $r -EA Stop).PSObject.Properties | Where-Object { $_.Name -match '^[A-Z_]+$' } | ForEach-Object { $v = $_.Value try { $b = [Security.Cryptography.ProtectedData]::Unprotect([Convert]::FromBase64String($v), $null, [Security.Cryptography.DataProtectionScope]::CurrentUser) $v = [Text.Encoding]::UTF8.GetString($b) } catch {} [Environment]::SetEnvironmentVariable($_.Name, $v, 'Process') } } catch {} if (-not (Get-Command claude -ErrorAction SilentlyContinue)) { Write-Host '' Write-Host ' [!] claude 命令未找到' -ForegroundColor Red Write-Host '' Write-Host ' 可能原因:' -ForegroundColor Yellow Write-Host ' 1. Claude Code 未安装 - 跑: npm i -g @anthropic-ai/claude-code' -ForegroundColor Gray Write-Host ' 2. npm 全局路径不在 PATH - 重跑 Bookworm-Setup.exe 修复' -ForegroundColor Gray Write-Host '' Write-Host ' 当前 PATH 片段 (诊断用):' -ForegroundColor Gray ($env:Path -split ';') | Where-Object { $_ -match 'npm|nodejs|pwsh|Git' } | ForEach-Object { Write-Host " $_" -ForegroundColor DarkGray } Write-Host '' return } & claude --dangerously-skip-permissions '@ # ─── Base64-UTF-16LE 编码 ───────────────────────────────── $bytes = [System.Text.Encoding]::Unicode.GetBytes($plainScript) $enc = [Convert]::ToBase64String($bytes) # 健康检查 if ($enc.Length -gt 7500) { throw "Base64 长度 $($enc.Length) 超 bat 变量安全上限 7500" } $bad = $enc -replace '[A-Za-z0-9+/=]', '' if ($bad) { throw "Base64 含非法字符: [$bad]" } Write-Host "[gen-launcher-bats] Base64 长度: $($enc.Length), 纯字符集检查 OK" -ForegroundColor Green # ─── bat 1: 启动Bookworm.bat ────────────────────────────── $launch = @" @echo off chcp 65001 > nul cd /d "%~dp0" :: 中转站在国内,不走代理 set NO_PROXY=bww.letcareme.com,code.letcareme.com,letcareme.com,localhost,127.0.0.1 set no_proxy=%NO_PROXY% :: 静默自动更新 (bookworm-boot + .claude 配置, 失败不阻断启动) echo [..] 检查更新... git pull --rebase >nul 2>nul git -C "%USERPROFILE%\.claude" pull --rebase >nul 2>nul set USE_WT=0 where wt >nul 2>nul && set USE_WT=1 set USE_PWSH7=0 where pwsh >nul 2>nul && set USE_PWSH7=1 :: v3.0.6: Base64-UTF-16LE (PATH 重载 + DPAPI 凭证加载 + claude 诊断 + 启动) :: 纯 A-Za-z0-9+/= 字符集, 避免 wt.exe 的 ';' 切 tab 误切 (修复 64856bc 症状一) :: -d "%CD%" 无尾反斜杠, 避免 -d "%~dp0" 的转义引号 (修复 0c33109 症状二) :: 重新生成: pwsh -NoProfile -File tools/gen-launcher-bats.ps1 set ENC=$enc :: 优先路径: wt + pwsh7 if %USE_WT% equ 1 if %USE_PWSH7% equ 1 ( start "" wt new-tab --title "Bookworm Smart Assistant" -d "%CD%" -- pwsh -NoLogo -NoExit -EncodedCommand %ENC% exit ) :: 路径 2: wt + powershell 5.1 if %USE_WT% equ 1 if %USE_PWSH7% equ 0 ( start "" wt new-tab --title "Bookworm Smart Assistant" -d "%CD%" -- powershell -NoLogo -ExecutionPolicy Bypass -NoExit -EncodedCommand %ENC% exit ) :: 路径 3: conhost + pwsh7 (无 wt 就不会有 ; 切 tab 问题, 但仍用 Base64 统一) if %USE_PWSH7% equ 1 ( start "Bookworm Smart Assistant" pwsh -NoLogo -NoExit -EncodedCommand %ENC% exit ) :: 路径 4: 回退 PowerShell 5.1 (最低保障, 交给 install.ps1 -StartOnly 处理) title Bookworm Portable echo. echo [!] PowerShell 7 未安装, 使用 PowerShell 5.1 echo. powershell -ExecutionPolicy Bypass -File install.ps1 -StartOnly -AutoAccept if %errorlevel% neq 0 ( echo. echo 启动失败,按任意键退出... pause > nul ) "@ # ─── bat 2: 更新并启动Bookworm.bat ─────────────────────── $update = @" @echo off chcp 65001 > nul cd /d "%~dp0" :: 中转站在国内,不走代理 set NO_PROXY=bww.letcareme.com,code.letcareme.com,letcareme.com,localhost,127.0.0.1 set no_proxy=%NO_PROXY% :: 静默自动更新 (bookworm-boot + .claude 配置) echo [..] 同步更新... git pull --rebase >nul 2>nul git -C "%USERPROFILE%\.claude" pull --rebase >nul 2>nul :: v3.0.6: 同启动Bookworm.bat 的 Base64 (DPAPI + PATH 重载 + claude 启动) set ENC=$enc :: 检测 pwsh7 可用性 where pwsh >nul 2>nul if %errorlevel% equ 0 ( :: pwsh7: 先同步配置 (SkipLaunch 不启动 claude), 再用 -EncodedCommand 在新窗口启动 pwsh -NoLogo -ExecutionPolicy Bypass -File "%~dp0install.ps1" -AutoAccept -SkipLaunch start "Bookworm Smart Assistant" pwsh -NoLogo -NoExit -EncodedCommand %ENC% exit ) :: 回退 PowerShell 5.1: 一次调用完成更新+加载凭证+启动 (消除双次调用) title Bookworm Portable powershell -ExecutionPolicy Bypass -File "%~dp0install.ps1" -AutoAccept if %errorlevel% neq 0 ( echo. echo 启动失败,按任意键退出... pause > nul ) "@ # ─── 写入 ───────────────────────────────────────────────── # bat 文件默认期望 GBK/ANSI, 但脚本顶部 chcp 65001 已切换到 UTF-8, 用无 BOM UTF-8 写入 [System.IO.File]::WriteAllText($launchBat, $launch, [System.Text.UTF8Encoding]::new($false)) [System.IO.File]::WriteAllText($updateBat, $update, [System.Text.UTF8Encoding]::new($false)) Write-Host "[gen-launcher-bats] ✓ 启动Bookworm.bat ($((Get-Item $launchBat).Length) bytes)" -ForegroundColor Green Write-Host "[gen-launcher-bats] ✓ 更新并启动Bookworm.bat ($((Get-Item $updateBat).Length) bytes)" -ForegroundColor Green # ─── Round-trip 验证 ───────────────────────────────────── $decoded = [System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($enc)) $err = $null [void][System.Management.Automation.Language.Parser]::ParseInput($decoded, [ref]$null, [ref]$err) if ($err) { throw "解码后脚本 PARSE ERR: $($err[0])" } Write-Host "[gen-launcher-bats] ✓ Round-trip PARSE OK ($($decoded.Length) chars)" -ForegroundColor Green