2026-04-26 15:11:14 +08:00
|
|
|
|
<#
|
|
|
|
|
|
.SYNOPSIS
|
2026-04-26 17:05:38 +08:00
|
|
|
|
v3.1.3: Bookworm 完整卸载实<EFBFBD><EFBFBD>脚本
|
2026-04-26 15:11:14 +08:00
|
|
|
|
|
|
|
|
|
|
.DESCRIPTION
|
|
|
|
|
|
由 卸载Bookworm.bat 调用. 集中所有 PS 清理逻辑, 避免 cmd 多行 PS 转义.
|
|
|
|
|
|
|
|
|
|
|
|
清理项:
|
|
|
|
|
|
[1] 桌面 4-5 个 .lnk (启动/更新/体检/卸载/旧 Bookworm.lnk)
|
|
|
|
|
|
[2] ~/.claude/ 整个目录 (skills/hooks/agents/凭证)
|
|
|
|
|
|
[3] HKCU:\Software\Bookworm (DPAPI 缓存 + Toast 备份)
|
|
|
|
|
|
[4] PS7 + PS5.1 双 profile.ps1 的 BW_CRED + BW_CLIP 块
|
|
|
|
|
|
[5] HKCU 截图 Toast 设置还原 (从备份)
|
|
|
|
|
|
[6] ANTHROPIC_* + BW_LICENSE_KEY User 环境变量
|
|
|
|
|
|
[7] 提示用户手动删 bookworm-boot 目录
|
|
|
|
|
|
|
|
|
|
|
|
保留 (公共依赖, 不主动卸):
|
|
|
|
|
|
- Node.js / Git / PowerShell 7 / Claude Code (npm i -g)
|
|
|
|
|
|
#>
|
|
|
|
|
|
|
|
|
|
|
|
$ErrorActionPreference = "Continue"
|
|
|
|
|
|
Add-Type -AssemblyName System.Windows.Forms -EA SilentlyContinue
|
|
|
|
|
|
|
|
|
|
|
|
# ── 二次确认 ──
|
|
|
|
|
|
$msg = "确定要卸载 Bookworm 吗?`n`n"
|
|
|
|
|
|
$msg += "将删除:`n"
|
|
|
|
|
|
$msg += " - 桌面 4-5 个快捷方式`n"
|
2026-04-26 17:05:38 +08:00
|
|
|
|
$msg += " - ~/.claude 中 Bookworm 注入的内容 (skills/hooks/agents/scripts)`n"
|
2026-04-26 15:11:14 +08:00
|
|
|
|
$msg += " - HKCU DPAPI 凭证缓存`n"
|
|
|
|
|
|
$msg += " - PowerShell profile (PS7+PS5.1) 中的 BW_* 块`n"
|
|
|
|
|
|
$msg += " - 还原截图 Toast 默认设置`n"
|
|
|
|
|
|
$msg += " - ANTHROPIC_* User 环境变量`n`n"
|
2026-04-26 17:05:38 +08:00
|
|
|
|
$msg += "保留:`n"
|
|
|
|
|
|
$msg += " - ~/.claude/CLAUDE.md, memory/, projects/ (用户自有内容)`n"
|
2026-04-26 15:11:14 +08:00
|
|
|
|
$msg += " - Node.js / Git / PowerShell 7 / Claude Code"
|
|
|
|
|
|
|
|
|
|
|
|
$confirm = [System.Windows.Forms.MessageBox]::Show($msg, 'Bookworm 卸载二次确认', 'YesNo', 'Warning')
|
|
|
|
|
|
if ($confirm -ne 'Yes') {
|
|
|
|
|
|
Write-Host "Bookworm 卸载已取消" -ForegroundColor Yellow
|
|
|
|
|
|
exit 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$logLines = @()
|
|
|
|
|
|
function Log { param([string]$m); Write-Host $m -ForegroundColor Cyan; $script:logLines += $m }
|
|
|
|
|
|
|
|
|
|
|
|
# ── [1/7] 桌面 .lnk ──
|
|
|
|
|
|
Log "[1/7] 删桌面快捷方式"
|
|
|
|
|
|
$desk = [Environment]::GetFolderPath('Desktop')
|
|
|
|
|
|
foreach ($n in @('启动Bookworm.lnk','更新Bookworm.lnk','体检Bookworm.lnk','卸载Bookworm.lnk','Bookworm.lnk')) {
|
|
|
|
|
|
$p = Join-Path $desk $n
|
|
|
|
|
|
if (Test-Path $p) {
|
|
|
|
|
|
try { Remove-Item $p -Force -EA Stop; Log " ✓ 删 $n" }
|
|
|
|
|
|
catch { Log " [!] 删 $n 失败: $_" }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-26 17:05:38 +08:00
|
|
|
|
# ── [2/7] ~/.claude Bookworm 注入内容 (精准删除, 保留用户自有配置) ──
|
|
|
|
|
|
Log "[2/7] 清 ~/.claude/ 中 Bookworm 注入的文件"
|
2026-04-26 15:11:14 +08:00
|
|
|
|
$claudeDir = Join-Path $env:USERPROFILE '.claude'
|
|
|
|
|
|
if (Test-Path $claudeDir) {
|
2026-04-26 17:05:38 +08:00
|
|
|
|
# 只删 Bookworm 管理的子目录和文件, 不删用户自己的 CLAUDE.md / memory / projects
|
|
|
|
|
|
$bwManagedDirs = @('skills', 'hooks', 'agents', 'scripts', 'constitution', 'patches', 'session-state')
|
|
|
|
|
|
foreach ($d in $bwManagedDirs) {
|
|
|
|
|
|
$dp = Join-Path $claudeDir $d
|
|
|
|
|
|
if (Test-Path $dp) {
|
|
|
|
|
|
try { Remove-Item $dp -Recurse -Force -EA Stop; Log " ✓ 删 $d/" }
|
|
|
|
|
|
catch { Log " [!] 删 $d/ 失败: $_" }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
# 删 Bookworm 的配置文件 (settings.json 含 hooks 注册)
|
|
|
|
|
|
foreach ($f in @('settings.json', 'settings.local.json', 'stats-compiled.json')) {
|
|
|
|
|
|
$fp = Join-Path $claudeDir $f
|
|
|
|
|
|
if (Test-Path $fp) {
|
|
|
|
|
|
try { Remove-Item $fp -Force -EA Stop; Log " ✓ 删 $f" }
|
|
|
|
|
|
catch { Log " [!] 删 $f 失败: $_" }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
Log " · 保留 ~/.claude/CLAUDE.md, memory/, projects/ (用户自有内容)"
|
2026-04-26 15:11:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ── [3/7] HKCU DPAPI 凭证 + Toast 备份元数据 ──
|
|
|
|
|
|
Log "[3/7] 清 HKCU:\Software\Bookworm DPAPI 凭证"
|
|
|
|
|
|
# 先读 Toast 备份, 后面 [5] 用
|
|
|
|
|
|
$toastOrig = $null
|
|
|
|
|
|
$bak = 'HKCU:\Software\Bookworm\ToastBackup'
|
|
|
|
|
|
if (Test-Path $bak) {
|
|
|
|
|
|
try { $toastOrig = (Get-ItemProperty -Path $bak -Name 'ScreenSketchToast_Original' -EA SilentlyContinue).ScreenSketchToast_Original } catch {}
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach ($r in @('HKCU:\Software\Bookworm\CachedEnv','HKCU:\Software\Bookworm\ToastBackup','HKCU:\Software\Bookworm')) {
|
|
|
|
|
|
if (Test-Path $r) {
|
|
|
|
|
|
try { Remove-Item $r -Recurse -Force -EA Stop; Log " ✓ 删 $r" }
|
|
|
|
|
|
catch { Log " [!] 删 $r 失败: $_" }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ── [4/7] profile.ps1 BW_CRED + BW_CLIP 块清理 (PS7+PS5.1) ──
|
|
|
|
|
|
Log "[4/7] 清 profile.ps1 BW_CRED + BW_CLIP 块"
|
|
|
|
|
|
foreach ($pdir in @(
|
|
|
|
|
|
(Join-Path $env:USERPROFILE 'Documents\PowerShell'),
|
|
|
|
|
|
(Join-Path $env:USERPROFILE 'Documents\WindowsPowerShell')
|
|
|
|
|
|
)) {
|
|
|
|
|
|
$pp = Join-Path $pdir 'profile.ps1'
|
|
|
|
|
|
if (-not (Test-Path $pp)) { continue }
|
|
|
|
|
|
try {
|
|
|
|
|
|
$c = Get-Content $pp -Raw -Encoding UTF8
|
|
|
|
|
|
$orig = $c.Length
|
|
|
|
|
|
# 兼容 v3.0.x / v3.1.x 所有 sentinel 版本
|
|
|
|
|
|
$c = [regex]::Replace($c, '# BW_CRED_START[\s\S]*?# BW_CRED_END\r?\n?', '')
|
|
|
|
|
|
$c = [regex]::Replace($c, '# BW_CLIP_START[\s\S]*?# BW_CLIP_END\r?\n?', '')
|
|
|
|
|
|
if ($c.Length -ne $orig) {
|
|
|
|
|
|
[System.IO.File]::WriteAllText($pp, $c, [System.Text.UTF8Encoding]::new($false))
|
|
|
|
|
|
Log " ✓ 清理 $pp (移除 $($orig - $c.Length) 字节)"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Log " · $pp 无 BW_* 块, 跳过"
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch { Log " [!] $pp 处理失败: $_" }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ── [5/7] 还原截图 Toast ──
|
|
|
|
|
|
Log "[5/7] 还原截图 Toast 设置"
|
|
|
|
|
|
$toastReg = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings\Microsoft.ScreenSketch_8wekyb3d8bbwe!App'
|
|
|
|
|
|
if ($toastOrig -eq '__ABSENT__') {
|
|
|
|
|
|
if (Test-Path $toastReg) {
|
|
|
|
|
|
try { Remove-ItemProperty -Path $toastReg -Name 'Enabled' -EA Stop; Log " ✓ Toast Enabled 项已删除 (恢复默认)" }
|
|
|
|
|
|
catch { Log " [!] Toast 还原失败: $_" }
|
|
|
|
|
|
}
|
|
|
|
|
|
} elseif ($toastOrig) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (-not (Test-Path $toastReg)) { New-Item -Path $toastReg -Force | Out-Null }
|
|
|
|
|
|
Set-ItemProperty -Path $toastReg -Name 'Enabled' -Value ([int]$toastOrig) -Type DWord -Force
|
|
|
|
|
|
Log " ✓ Toast Enabled 还原为 $toastOrig"
|
|
|
|
|
|
} catch { Log " [!] Toast 还原失败: $_" }
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Log " · 无 Toast 备份记录, 跳过"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ── [6/7] ANTHROPIC_* User env ──
|
|
|
|
|
|
Log "[6/7] 清 ANTHROPIC_* / BW_LICENSE_KEY User 环境变量"
|
|
|
|
|
|
foreach ($ev in @('ANTHROPIC_API_KEY','ANTHROPIC_BASE_URL','ANTHROPIC_MODEL','BW_LICENSE_KEY')) {
|
|
|
|
|
|
$v = [Environment]::GetEnvironmentVariable($ev, 'User')
|
|
|
|
|
|
if ($v) {
|
|
|
|
|
|
try { [Environment]::SetEnvironmentVariable($ev, $null, 'User'); Log " ✓ 清 $ev" }
|
|
|
|
|
|
catch { Log " [!] 清 $ev 失败: $_" }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ── [7/7] 提示手动删 bookworm-boot ──
|
|
|
|
|
|
Log "[7/7] 手动收尾"
|
|
|
|
|
|
Log " 请手动删除 bookworm-boot 目录 (本脚本无法删除自身所在目录):"
|
|
|
|
|
|
Log " 例如: $env:USERPROFILE\Downloads\bookworm-boot"
|
|
|
|
|
|
|
|
|
|
|
|
# ── 完成弹窗 ──
|
|
|
|
|
|
$endMsg = "Bookworm 卸载完成.`n`n"
|
|
|
|
|
|
$endMsg += "执行摘要:`n"
|
|
|
|
|
|
$endMsg += ($logLines -join "`n")
|
|
|
|
|
|
$endMsg += "`n`n保留的公共依赖 (如不再需要可手动卸):`n"
|
|
|
|
|
|
$endMsg += " - Node.js: %ProgramFiles%\nodejs`n"
|
|
|
|
|
|
$endMsg += " - Git for Windows: %ProgramFiles%\Git`n"
|
|
|
|
|
|
$endMsg += " - PowerShell 7: %ProgramFiles%\PowerShell\7`n"
|
|
|
|
|
|
$endMsg += " - Claude Code: 命令行运行 npm uninstall -g @anthropic-ai/claude-code"
|
|
|
|
|
|
[System.Windows.Forms.MessageBox]::Show($endMsg, 'Bookworm 卸载完成', 'OK', 'Information') | Out-Null
|
|
|
|
|
|
exit 0
|