bookworm-boot/build.ps1
bookworm 17c600fe93 feat(installer): GUI 进度窗 + uv 三层 fallback + 桌面专用图标 + 静默化
修复 v1.5.1 用户实测发现的两个体验问题:

1. **uv 安装失败 + RemoteException 弹窗** (auto-setup.ps1)
   - 旧逻辑: python -m pip install uv (网络/权限/$ErrorActionPreference=Stop 易触发)
   - 新逻辑: 三层 fallback (winget → Astral 官方脚本 → pip), 全程 SilentlyContinue
   - 失败仅写入 $TEMP/bookworm-uv-install.log, 不阻断不弹窗 (uv 是可选依赖)

2. **PS2EXE -NoConsole 把 Log-X 弹窗化** (build.ps1)
   - 加 -NoOutput + -NoError, 所有 Write-Host 静默吞掉
   - 用户不再被 70+ 个 [!] 弹窗轰炸

3. **静默后无进度反馈 → GUI 进度窗口** (auto-setup.ps1)
   - 新增 Show-ProgressForm/Update-Progress/Update-Progress-SubStatus/Close-ProgressForm
   - 顶部常驻 Form: 标题 + Phase 标签 + 当前状态 + 进度条 + 日志路径
   - 所有 Log-X 改写日志文件 ($TEMP/bookworm-setup-{ts}.log) + 更新进度窗口

4. **桌面专用图标** (auto-setup.ps1 + bookworm-desktop.ico)
   - 从 og-image.png 自动检测蓝紫渐变 B 圆 → 圆形 alpha mask → 7 尺寸 ICO (86 KB)
   - New-DesktopShortcuts 增加 IconLocation, 桌面快捷方式显示 Bookworm 主图标
   - 主图比 favicon 神经螺旋更突出, 48px 也清晰可辨

5. **Phase 7 安装完成 banner**: Write-Host → Show-MsgBox
6. **Claude Code 启动**: 主进程启动 → Start-Process cmd /k claude (新窗口)

构建验证: 7/7 补丁字符串 (Show-ProgressForm/BWLogFile/winget/astral/
bookworm-desktop.ico/IconLocation 等) 经 EXE 字符串扫描确认编译进 build artifact.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 20:02:53 +08:00

171 lines
7.0 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<#
.SYNOPSIS
Bookworm Portable — 打包工具 (管理员使用)
.DESCRIPTION
将 auto-setup.ps1 打包为 Bookworm-Setup.exe (PS2EXE)
将 gen-authcode.js 打包为 gen-authcode.exe (pkg)
输出到 dist\ 目录
.USAGE
.\build.ps1 # 打包两个
.\build.ps1 -Setup # 只打包用户安装器
.\build.ps1 -Admin # 只打包管理员工具
#>
param(
[switch]$Setup, # 只打 Bookworm-Setup.exe
[switch]$Admin # 只打 gen-authcode.exe
)
$ErrorActionPreference = "Stop"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$DistDir = Join-Path $ScriptDir "dist"
# 默认两个都打
$buildSetup = $Setup -or (-not $Setup -and -not $Admin)
$buildAdmin = $Admin -or (-not $Setup -and -not $Admin)
function Write-Step($msg) {
Write-Host ""
Write-Host " ── $msg" -ForegroundColor Cyan
}
function Write-OK($msg) { Write-Host " [OK] $msg" -ForegroundColor Green }
function Write-Warn($msg) { Write-Host " [!] $msg" -ForegroundColor Yellow }
function Write-Fail($msg) { Write-Host " [!!] $msg" -ForegroundColor Red }
Write-Host ""
Write-Host " +------------------------------------------+" -ForegroundColor Cyan
Write-Host " | Bookworm Portable — Build Script |" -ForegroundColor Cyan
Write-Host " +------------------------------------------+" -ForegroundColor Cyan
if (-not (Test-Path $DistDir)) {
New-Item -ItemType Directory $DistDir | Out-Null
Write-OK "创建 dist\ 目录"
}
# ════════════════════════════════════════════════════════
# 1. Bookworm-Setup.exe (auto-setup.ps1 → PS2EXE)
# ════════════════════════════════════════════════════════
if ($buildSetup) {
Write-Step "打包 Bookworm-Setup.exe (PS2EXE)"
# 安装/检查 PS2EXE
if (-not (Get-Command Invoke-ps2exe -ErrorAction SilentlyContinue)) {
Write-Warn "PS2EXE 未安装,正在安装..."
Install-Module ps2exe -Scope CurrentUser -Force -AllowClobber
Import-Module ps2exe
}
$inputPs1 = Join-Path $ScriptDir "auto-setup.ps1"
$outputExe = Join-Path $DistDir "Bookworm-Setup.exe"
if (-not (Test-Path $inputPs1)) {
Write-Fail "找不到 auto-setup.ps1"
exit 1
}
Write-Host " 输入: $inputPs1" -ForegroundColor Gray
Write-Host " 输出: $outputExe" -ForegroundColor Gray
$iconFile = Join-Path $ScriptDir "bookworm.ico"
$ps2exeArgs = @{
InputFile = $inputPs1
OutputFile = $outputExe
Title = "Bookworm Portable Setup"
Description = "Bookworm Smart Assistant 安装向导"
Company = "Bookworm"
Version = "1.5.1.0"
NoConsole = $true
NoOutput = $true # 抑制所有 Write-Host 弹窗化, 只保留 Show-MsgBox / GUI dialog
NoError = $true # 抑制 stderr 弹窗化, 异常仍走 try-catch
}
if (Test-Path $iconFile) {
$ps2exeArgs.IconFile = $iconFile
Write-Host " 图标: $iconFile" -ForegroundColor Gray
}
Invoke-ps2exe @ps2exeArgs
if (Test-Path $outputExe) {
$sizeKB = [math]::Round((Get-Item $outputExe).Length / 1KB)
Write-OK "Bookworm-Setup.exe 打包完成 (${sizeKB} KB)"
} else {
Write-Fail "Bookworm-Setup.exe 打包失败"
exit 1
}
}
# ════════════════════════════════════════════════════════
# 2. gen-authcode.exe (gen-authcode.js → pkg)
# ════════════════════════════════════════════════════════
if ($buildAdmin) {
Write-Step "打包 gen-authcode.exe (pkg)"
# 检查 Node.js
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
Write-Fail "需要 Node.js请先安装: https://nodejs.org"
exit 1
}
# 安装/检查 pkg
# 优先找 npm global bin 目录下的 pkg不依赖 PATH 是否刷新)
$npmGlobalBin = Join-Path (npm root -g 2>$null) "..\pkg.cmd" | Resolve-Path -ErrorAction SilentlyContinue
$pkgCmd = if ($npmGlobalBin) { $npmGlobalBin.Path } else { (Get-Command pkg -ErrorAction SilentlyContinue)?.Source }
if (-not $pkgCmd) {
Write-Warn "pkg 未安装,正在安装..."
npm install -g pkg
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" +
[System.Environment]::GetEnvironmentVariable("Path","User")
$npmGlobalBin = Join-Path (npm root -g 2>$null) "..\pkg.cmd" | Resolve-Path -ErrorAction SilentlyContinue
$pkgCmd = $npmGlobalBin.Path
}
$inputJs = Join-Path $ScriptDir "gen-authcode.js"
$outputExe = Join-Path $DistDir "gen-authcode.exe"
if (-not (Test-Path $inputJs)) {
Write-Fail "找不到 gen-authcode.js"
exit 1
}
Write-Host " 输入: $inputJs" -ForegroundColor Gray
Write-Host " 输出: $outputExe" -ForegroundColor Gray
Write-Host " (内嵌 Node.js 运行时,首次打包约 1 分钟)" -ForegroundColor Gray
& $pkgCmd $inputJs --targets node18-win-x64 --output $outputExe 2>&1 |
ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
if (Test-Path $outputExe) {
$sizeMB = [math]::Round((Get-Item $outputExe).Length / 1MB, 1)
Write-OK "gen-authcode.exe 打包完成 (${sizeMB} MB)"
# 注入图标 (rcedit)
$iconFile = Join-Path $ScriptDir "bookworm.ico"
$rcedit = "$env:APPDATA\npm\node_modules\rcedit\bin\rcedit-x64.exe"
if ((Test-Path $iconFile) -and (Test-Path $rcedit)) {
& $rcedit $outputExe --set-icon $iconFile | Out-Null
Write-OK "gen-authcode.exe 图标注入完成"
}
} else {
Write-Fail "gen-authcode.exe 打包失败"
exit 1
}
}
# ════════════════════════════════════════════════════════
# 完成
# ════════════════════════════════════════════════════════
Write-Host ""
Write-Host " ============================================" -ForegroundColor Green
Write-Host " 打包完成!输出目录: dist\" -ForegroundColor Green
Write-Host " ============================================" -ForegroundColor Green
Write-Host ""
Get-ChildItem $DistDir | ForEach-Object {
$sizeMB = [math]::Round($_.Length / 1MB, 1)
Write-Host " $($_.Name.PadRight(30)) ${sizeMB} MB" -ForegroundColor White
}
Write-Host ""
Write-Host " 分发说明:" -ForegroundColor Gray
Write-Host " Bookworm-Setup.exe → 放入 bookworm-boot 仓库根目录,发给用户" -ForegroundColor Gray
Write-Host " gen-authcode.exe → 管理员本机使用,勿对外分发" -ForegroundColor Gray
Write-Host ""