|
| 1 | +<# |
| 2 | +.SYNOPSIS |
| 3 | + drpys 一键卸载脚本(最终容错版) |
| 4 | +.DESCRIPTION |
| 5 | + 1) 删除任务计划 |
| 6 | + 2) 停止并删除 PM2 进程 |
| 7 | + 3) 结束残余 Node 进程 |
| 8 | + 4) 删除源码目录 |
| 9 | + 5) 可选:卸载运行环境(Node、Python、nvm、Git、yarn、pm2) |
| 10 | +.PARAMETER SkipConfirm |
| 11 | + 静默模式 |
| 12 | +.PARAMETER IncludeEnv |
| 13 | + 强制连环境一起删 |
| 14 | +.PARAMETER UseProxy |
| 15 | + 下载时使用代理 |
| 16 | +.PARAMETER ProxyHost |
| 17 | + 代理地址,默认 127.0.0.1:7890 |
| 18 | +#> |
| 19 | + |
| 20 | +param( |
| 21 | + [switch]$SkipConfirm, |
| 22 | + [switch]$IncludeEnv, |
| 23 | + [switch]$UseProxy, |
| 24 | + [string]$ProxyHost = "127.0.0.1:7890" |
| 25 | +) |
| 26 | +$ErrorActionPreference = "Stop" |
| 27 | + |
| 28 | +# ---------- 1. 自动提权 ---------- |
| 29 | +if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { |
| 30 | + Write-Host "当前非管理员权限,正在尝试以管理员身份重新启动..." -ForegroundColor Yellow |
| 31 | + $arguments = "-NoProfile -ExecutionPolicy Bypass -File `"$($MyInvocation.MyCommand.Path)`"" |
| 32 | + if ($SkipConfirm) { $arguments += " -SkipConfirm" } |
| 33 | + if ($IncludeEnv) { $arguments += " -IncludeEnv" } |
| 34 | + if ($UseProxy) { $arguments += " -UseProxy -ProxyHost `"$ProxyHost`"" } |
| 35 | + Start-Process powershell -ArgumentList $arguments -Verb RunAs |
| 36 | + exit |
| 37 | +} |
| 38 | +Set-Location -LiteralPath $PSScriptRoot |
| 39 | + |
| 40 | +# ---------- 2. 代理 & 工具 ---------- |
| 41 | +function Use-ProxyIfNeeded ([scriptblock]$Script) { |
| 42 | + if ($UseProxy) { |
| 43 | + $oldHttp = [Environment]::GetEnvironmentVariable("HTTP_PROXY") |
| 44 | + $oldHttps = [Environment]::GetEnvironmentVariable("HTTPS_PROXY") |
| 45 | + [Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://$ProxyHost", "Process") |
| 46 | + [Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://$ProxyHost", "Process") |
| 47 | + try { & $Script } finally { |
| 48 | + [Environment]::SetEnvironmentVariable("HTTP_PROXY", $oldHttp, "Process") |
| 49 | + [Environment]::SetEnvironmentVariable("HTTPS_PROXY", $oldHttps, "Process") |
| 50 | + } |
| 51 | + } else { & $Script } |
| 52 | +} |
| 53 | +function Test-Cmd ([string]$cmd) { $null -ne (Get-Command $cmd -ErrorAction SilentlyContinue) } |
| 54 | + |
| 55 | +# ---------- 3. 交互确认 ---------- |
| 56 | +if (-not $SkipConfirm) { |
| 57 | + Write-Host "========== drpys 卸载脚本 ==========" -ForegroundColor Cyan |
| 58 | + Write-Host "请选择卸载方式:" -ForegroundColor Yellow |
| 59 | + Write-Host " 1) 仅删除项目(保留环境)" |
| 60 | + Write-Host " 2) 删除项目 + 卸载运行环境" |
| 61 | + $choice = Read-Host "请输入对应数字(1/2)默认(1)" |
| 62 | + $IncludeEnv = ($choice -eq "2") |
| 63 | +} |
| 64 | + |
| 65 | +# ---------- 4. 任务计划 ---------- |
| 66 | +"drpyS_PM2_Startup","drpyS_Update" | ForEach-Object { |
| 67 | + if (Get-ScheduledTask -TaskName $_ -ErrorAction SilentlyContinue) { |
| 68 | + Write-Host "删除任务计划 $_ ..." -ForegroundColor Green |
| 69 | + Unregister-ScheduledTask -TaskName $_ -Confirm:$false |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +# ---------- 5. PM2 进程 ---------- |
| 74 | +if (Test-Cmd "pm2") { |
| 75 | + Write-Host "停止并删除 PM2 进程 drpyS ..." -ForegroundColor Green |
| 76 | + pm2 stop drpyS *>$null |
| 77 | + pm2 delete drpyS *>$null |
| 78 | + pm2 save *>$null |
| 79 | +} |
| 80 | + |
| 81 | +# ---------- 6. 结束残余 Node ---------- |
| 82 | +Get-Process -Name "node" -ErrorAction SilentlyContinue | ForEach-Object { |
| 83 | + Write-Host "结束残余 Node 进程 PID $($_.Id) ..." -ForegroundColor Green |
| 84 | + Stop-Process -Id $_.Id -Force |
| 85 | +} |
| 86 | + |
| 87 | +# ---------- 7. 删除源码 ---------- |
| 88 | +$repoDir = Read-Host "请输入项目存放目录(留空则使用当前目录)" |
| 89 | +if ([string]::IsNullOrWhiteSpace($repoDir)) { $repoDir = (Get-Location).Path } |
| 90 | +$projectPath = Join-Path $repoDir "drpy-node" |
| 91 | +if (Test-Path $projectPath) { |
| 92 | + Write-Host "删除源码目录 $projectPath ..." -ForegroundColor Green |
| 93 | + Remove-Item -Recurse -Force $projectPath |
| 94 | +} else { |
| 95 | + Write-Host "未检测到源码目录,跳过删除" -ForegroundColor Yellow |
| 96 | +} |
| 97 | + |
| 98 | +# ---------- 8. 卸载运行环境(与安装脚本一一对应) ---------- |
| 99 | +if ($IncludeEnv) { |
| 100 | + Write-Host "开始卸载运行环境(与安装脚本对应)..." -ForegroundColor Yellow |
| 101 | + |
| 102 | + # 1) Node 20.18.3 用 nvm 卸载 |
| 103 | + if (Test-Cmd "nvm") { |
| 104 | + Write-Host "使用 nvm 卸载 Node 20.18.3 ..." -ForegroundColor Green |
| 105 | + nvm uninstall 20.18.3 2>$null |
| 106 | + # 如果这是最后一个版本,nvm 本身仍保留,用户可手动在「应用和功能」里再卸 nvm |
| 107 | + } else { |
| 108 | + Write-Host "未检测到 nvm,跳过 Node 版本卸载" -ForegroundColor Yellow |
| 109 | + } |
| 110 | + |
| 111 | + # 2) Python 3.11 —— 安装脚本里直接解压到 C:\Python311 并写注册表/追加 PATH |
| 112 | + $pyDir = "C:\Python311" |
| 113 | + if (Test-Path $pyDir) { |
| 114 | + Write-Host "删除 Python 3.11 目录 $pyDir ..." -ForegroundColor Green |
| 115 | + Remove-Item -Recurse -Force $pyDir -ErrorAction SilentlyContinue |
| 116 | + } |
| 117 | + |
| 118 | + # 3) Git —— 安装脚本用 winget 装的,直接用 winget 卸载 |
| 119 | + try { |
| 120 | + Write-Host "winget 卸载 Git..." -ForegroundColor Green |
| 121 | + winget uninstall --id Git.Git -e --accept-source-agreements --silent |
| 122 | + } catch { |
| 123 | + Write-Warning "Git winget 卸载失败,请手动在「应用和功能」里卸载" |
| 124 | + } |
| 125 | + |
| 126 | + # 4) yarn / pm2 —— 安装脚本 npm -g 装的,npm -g 卸载 |
| 127 | + if (Test-Cmd "npm") { |
| 128 | + Write-Host "npm 全局卸载 yarn、pm2 ..." -ForegroundColor Green |
| 129 | + npm uninstall -g yarn pm2 *>$null |
| 130 | + } |
| 131 | + |
| 132 | + Write-Host "运行环境卸载步骤结束,如有残留请手动到「应用和功能」确认。" -ForegroundColor Yellow |
| 133 | +} |
| 134 | + |
| 135 | +# ---------- 9. 完成 ---------- |
| 136 | +Write-Host "drpys 卸载完成!" -ForegroundColor Green |
| 137 | +Write-Host "按任意键退出!!!" -ForegroundColor Green |
| 138 | +Read-Host |
0 commit comments