v3.0.3: Win10 PS7 MSI fallback (when winget absent/outdated)

Phase 1 依赖循环增加 MSI 直链兜底:
- winget 失败 or 缺席 -> Invoke-WebRequest 拉 PS 7.4.6 MSI
- 强制 TLS 1.2 (Win10 默认 TLS 1.0 访问 GitHub 会断)
- msiexec /quiet /qn ADD_PATH=1 静默装
- 装后补 PATH (PS7 装完默认不在 PATH 直到重登)

同时将 PowerShell 7 改为 Core=true, winget/MSI 都失败会明确提示用户.

背景: 第二/第三台 Win10 开机一直用 PS 5.1, 原因 pwsh 未装 (winget 静默失败),
bat 路径 3/4 fallback 到 5.1, Unicode/TUI 体验差.
This commit is contained in:
Bookworm Admin 2026-04-21 14:31:32 +08:00
parent 18210ac497
commit 13337134bc

View File

@ -20,7 +20,7 @@ param(
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
# ─── 版本号 (每次更新递增, build.ps1 自动读取) ────── # ─── 版本号 (每次更新递增, build.ps1 自动读取) ──────
$BWVersion = "3.0.2" # +ExecutionPolicy +WM_SETTINGCHANGE 广播 +.claude.json 预填跳过 v2.0.1 登录画面 $BWVersion = "3.0.3" # +PS7 MSI 直链兜底 (Win10 无 winget 仍能装 pwsh, 避免跌落到 PS 5.1)
# DryRun 模式日志标记 # DryRun 模式日志标记
if ($DryRun) { $global:BWDryRun = $DryRun } else { $global:BWDryRun = $null } if ($DryRun) { $global:BWDryRun = $DryRun } else { $global:BWDryRun = $null }
@ -779,7 +779,7 @@ $deps = @(
# 核心依赖 (缺失则尝试自动安装) # 核心依赖 (缺失则尝试自动安装)
@{ Name = "Node.js"; Cmd = "node"; WingetId = "OpenJS.NodeJS.LTS"; NpmPkg = $null; PipPkg = $null; Core = $true } @{ Name = "Node.js"; Cmd = "node"; WingetId = "OpenJS.NodeJS.LTS"; NpmPkg = $null; PipPkg = $null; Core = $true }
@{ Name = "Git"; Cmd = "git"; WingetId = "Git.Git"; NpmPkg = $null; PipPkg = $null; Core = $true } @{ Name = "Git"; Cmd = "git"; WingetId = "Git.Git"; NpmPkg = $null; PipPkg = $null; Core = $true }
@{ Name = "PowerShell 7"; Cmd = "pwsh"; WingetId = "Microsoft.PowerShell"; NpmPkg = $null; PipPkg = $null; Core = $false } @{ Name = "PowerShell 7"; Cmd = "pwsh"; WingetId = "Microsoft.PowerShell"; NpmPkg = $null; PipPkg = $null; Core = $true; MsiUrl = "https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/PowerShell-7.4.6-win-x64.msi" }
@{ Name = "Claude Code"; Cmd = "claude"; WingetId = $null; NpmPkg = "@anthropic-ai/claude-code"; PipPkg = $null; Core = $true } @{ Name = "Claude Code"; Cmd = "claude"; WingetId = $null; NpmPkg = "@anthropic-ai/claude-code"; PipPkg = $null; Core = $true }
# Python 移到可选依赖 (不在此列表, 由 line 753 单独处理) # Python 移到可选依赖 (不在此列表, 由 line 753 单独处理)
) )
@ -808,6 +808,31 @@ foreach ($dep in $deps) {
Log-Fail "$($dep.Name) 安装失败: $_" Log-Fail "$($dep.Name) 安装失败: $_"
} }
} }
# v3.0.3: winget 缺席/失败时, 用 MSI 直链兜底 (主要针对 Win10 21H1 及更早版本无 winget / AppInstaller 过老)
if (-not (Test-Cmd $dep.Cmd) -and $dep.MsiUrl) {
Log-Warn "$($dep.Name) winget 路径失败, 改走 MSI 直链..."
$msiPath = Join-Path $env:TEMP "bw-$($dep.Cmd)-installer.msi"
try {
# TLS 1.2 强制 (Win10 默认 TLS 1.0/1.1 访问 GitHub 会断)
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Log-Info " 下载 $($dep.MsiUrl.Substring($dep.MsiUrl.LastIndexOf('/')+1))"
Invoke-WebRequest -Uri $dep.MsiUrl -OutFile $msiPath -UseBasicParsing -TimeoutSec 300 -EA Stop
if ((Get-Item $msiPath).Length -lt 1MB) { throw "MSI 下载不完整: $((Get-Item $msiPath).Length) bytes" }
Log-Info " 安装 MSI (静默, 需 1-2 分钟)..."
$p = Start-Process "msiexec.exe" -ArgumentList "/i", "`"$msiPath`"", "/quiet", "/qn", "/norestart", "ADD_PATH=1" -Wait -PassThru -NoNewWindow
Remove-Item $msiPath -Force -EA SilentlyContinue
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
# PS7 MSI 默认装到 %ProgramFiles%\PowerShell\7\pwsh.exe, 强制补 PATH
$ps7Dir = "$env:ProgramFiles\PowerShell\7"
if ((Test-Path "$ps7Dir\pwsh.exe") -and ($env:Path -notlike "*$ps7Dir*")) { $env:Path = "$ps7Dir;$env:Path" }
if (Test-Cmd $dep.Cmd) {
Log-OK "$($dep.Name) MSI 安装成功 (exit $($p.ExitCode))"
$installed += $dep.Name
} else {
Log-Fail "$($dep.Name) MSI 安装后仍找不到 pwsh (exit $($p.ExitCode))"
}
} catch { Log-Fail "$($dep.Name) MSI 直链失败: $_" }
}
elseif ($dep.NpmPkg -and (Test-Cmd "npm")) { elseif ($dep.NpmPkg -and (Test-Cmd "npm")) {
try { try {
$r = Run-CmdWithUI "npm" @("i", "-g", $dep.NpmPkg) "npm 安装 $($dep.Name)" 120000 $r = Run-CmdWithUI "npm" @("i", "-g", $dep.NpmPkg) "npm 安装 $($dep.Name)" 120000