Skip to content

Commit 1e9d9bb

Browse files
authored
Merge pull request #45 from sanshu-rom/patch-9
升级卸载逻辑,增加成功率
2 parents d6ce2eb + 8558554 commit 1e9d9bb

File tree

1 file changed

+152
-62
lines changed

1 file changed

+152
-62
lines changed

install/uninstall.ps1

Lines changed: 152 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<#
22
.SYNOPSIS
3-
drpys 一键卸载脚本(最终容错版
3+
drpys 一键卸载脚本(与安装脚本完全对应版
44
.DESCRIPTION
5-
1) 删除任务计划
6-
2) 停止并删除 PM2 进程
7-
3) 结束残余 Node 进程
8-
4) 删除源码目录
9-
5) 可选:卸载运行环境(NodePython、nvm、Gityarnpm2)
5+
1) 删除任务计划
6+
2) 停止并删除 PM2 进程
7+
3) 结束残余 Node 进程
8+
4) 删除源码目录
9+
5) 可选:卸载运行环境(Node / Python / Git / nvm / yarn / pm2)
1010
.PARAMETER SkipConfirm
1111
静默模式
1212
.PARAMETER IncludeEnv
@@ -16,29 +16,29 @@
1616
.PARAMETER ProxyHost
1717
代理地址,默认 127.0.0.1:7890
1818
#>
19-
2019
param(
21-
[switch]$SkipConfirm,
22-
[switch]$IncludeEnv,
2320
[switch]$UseProxy,
24-
[string]$ProxyHost = "127.0.0.1:7890"
21+
[string]$ProxyHost = "127.0.0.1:7890",
22+
[switch]$SkipConfirm,
23+
[switch]$IncludeEnv
2524
)
26-
$ErrorActionPreference = "Stop"
25+
$ErrorActionPreference = "Continue" # 全局容错
2726

2827
# ---------- 1. 自动提权 ----------
2928
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
3029
Write-Host "当前非管理员权限,正在尝试以管理员身份重新启动..." -ForegroundColor Yellow
3130
$arguments = "-NoProfile -ExecutionPolicy Bypass -File `"$($MyInvocation.MyCommand.Path)`""
31+
if ($UseProxy) { $arguments += " -UseProxy -ProxyHost `"$ProxyHost`"" }
3232
if ($SkipConfirm) { $arguments += " -SkipConfirm" }
3333
if ($IncludeEnv) { $arguments += " -IncludeEnv" }
34-
if ($UseProxy) { $arguments += " -UseProxy -ProxyHost `"$ProxyHost`"" }
3534
Start-Process powershell -ArgumentList $arguments -Verb RunAs
3635
exit
3736
}
3837
Set-Location -LiteralPath $PSScriptRoot
3938

40-
# ---------- 2. 代理 & 工具 ----------
41-
function Use-ProxyIfNeeded ([scriptblock]$Script) {
39+
# ---------- 2. 代理 ----------
40+
function Use-ProxyIfNeeded {
41+
param([scriptblock]$Script)
4242
if ($UseProxy) {
4343
$oldHttp = [Environment]::GetEnvironmentVariable("HTTP_PROXY")
4444
$oldHttps = [Environment]::GetEnvironmentVariable("HTTPS_PROXY")
@@ -50,9 +50,8 @@ function Use-ProxyIfNeeded ([scriptblock]$Script) {
5050
}
5151
} else { & $Script }
5252
}
53-
function Test-Cmd ([string]$cmd) { $null -ne (Get-Command $cmd -ErrorAction SilentlyContinue) }
5453

55-
# ---------- 3. 交互确认 ----------
54+
# ---------- 3. 用户确认 ----------
5655
if (-not $SkipConfirm) {
5756
Write-Host "========== drpys 卸载脚本 ==========" -ForegroundColor Cyan
5857
Write-Host "请选择卸载方式:" -ForegroundColor Yellow
@@ -64,75 +63,166 @@ if (-not $SkipConfirm) {
6463

6564
# ---------- 4. 任务计划 ----------
6665
"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
66+
try {
67+
if (Get-ScheduledTask -TaskName $_ -ErrorAction SilentlyContinue) {
68+
Write-Host "删除任务计划 $_ ..." -ForegroundColor Green
69+
Unregister-ScheduledTask -TaskName $_ -Confirm:$false -ErrorAction SilentlyContinue
70+
}
71+
} catch {
72+
Write-Warning "删除任务计划 $_ 失败,跳过..."
7073
}
7174
}
7275

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
76+
# ---------- 5. PM2 & Node 进程 ----------
77+
try {
78+
if (Get-Command pm2 -ErrorAction SilentlyContinue) {
79+
Write-Host "停止并删除 PM2 进程 drpyS ..." -ForegroundColor Green
80+
pm2 stop drpyS *>$null
81+
pm2 delete drpyS *>$null
82+
pm2 save *>$null
83+
}
84+
} catch {
85+
Write-Warning "PM2 进程操作失败,跳过..."
7986
}
8087

81-
# ---------- 6. 结束残余 Node ----------
8288
Get-Process -Name "node" -ErrorAction SilentlyContinue | ForEach-Object {
83-
Write-Host "结束残余 Node 进程 PID $($_.Id) ..." -ForegroundColor Green
84-
Stop-Process -Id $_.Id -Force
89+
try {
90+
Write-Host "结束残余 Node 进程 PID $($_.Id) ..." -ForegroundColor Green
91+
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
92+
} catch {
93+
Write-Warning "结束 Node 进程 $($_.Id) 失败,跳过..."
94+
}
8595
}
8696

87-
# ---------- 7. 删除源码 ----------
97+
# ---------- 6. 删除源码 ----------
8898
$repoDir = Read-Host "请输入项目存放目录(留空则使用当前目录)"
8999
if ([string]::IsNullOrWhiteSpace($repoDir)) { $repoDir = (Get-Location).Path }
90100
$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
101+
try {
102+
if (Test-Path $projectPath) {
103+
Write-Host "删除源码目录 $projectPath ..." -ForegroundColor Green
104+
Remove-Item -Recurse -Force $projectPath -ErrorAction SilentlyContinue
105+
} else {
106+
Write-Host "未检测到源码目录,跳过删除" -ForegroundColor Yellow
107+
}
108+
} catch {
109+
Write-Warning "删除源码目录失败,跳过..."
96110
}
97111

98-
# ---------- 8. 卸载运行环境(与安装脚本一一对应) ----------
112+
# ---------- 7. 卸载运行环境(与安装脚本 100% 对应,注册表定位卸载) ----------
99113
if ($IncludeEnv) {
100-
Write-Host "开始卸载运行环境(与安装脚本对应)..." -ForegroundColor Yellow
114+
Write-Host "开始卸载运行环境(与安装脚本完全对应)..." -ForegroundColor Yellow
101115

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-
}
116+
# 1) 卸载全局 npm 包
117+
try {
118+
if (Get-Command npm -ErrorAction SilentlyContinue) {
119+
Write-Host "卸载全局 npm 包 (yarn, pm2)..." -ForegroundColor Green
120+
npm uninstall -g yarn pm2 *>$null
121+
}
122+
} catch { Write-Warning "npm 卸载全局包失败: $($_.Exception.Message)" }
110123

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-
}
124+
# 2) 卸载 NVM for Windows(NSIS) + Node
125+
try {
126+
$nvmReg = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" |
127+
ForEach-Object { Get-ItemProperty $_.PSPath } |
128+
Where-Object { $_.DisplayName -match "NVM for Windows" } |
129+
Select-Object -First 1
130+
if ($nvmReg -and $nvmReg.UninstallString) {
131+
Write-Host "卸载 NVM for Windows ..." -ForegroundColor Green
132+
Write-Host "如果弹出卸载窗口请手动确认操作 ..." -ForegroundColor Yellow
133+
Start-Process -FilePath $nvmReg.UninstallString -ArgumentList "/S" -Wait
134+
}
135+
# 强制删目录
136+
$nvmDir = "${env:ProgramFiles}\nvm"
137+
if (Test-Path $nvmDir) { Remove-Item -Recurse -Force $nvmDir -ErrorAction SilentlyContinue }
138+
$envPaths = [Environment]::GetEnvironmentVariable("PATH", "Machine") -split ';'
139+
$clean = $envPaths | Where-Object { $_ -notmatch '\\nvm\\?' -and $_ -notmatch '\\nodejs\\?' }
140+
[Environment]::SetEnvironmentVariable("PATH", ($clean -join ';'), "Machine")
141+
} catch { Write-Warning "NVM 卸载失败: $($_.Exception.Message)" }
117142

118-
# 3) Git —— 安装脚本用 winget 装的,直接用 winget 卸载
143+
# ---------- 卸载 Python 3.11.9 ----------
119144
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-
}
145+
# 1) 先杀可能占用的进程(去掉 idle)
146+
'python', 'pythonw', 'pip', 'code' | ForEach-Object {
147+
Get-Process $_ -ErrorAction SilentlyContinue |
148+
Where-Object { $_.ProcessName -ne 'Idle' } |
149+
Stop-Process -Force -ErrorAction SilentlyContinue
150+
}
151+
152+
# 2) 找卸载命令
153+
$pyReg = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" |
154+
ForEach-Object { Get-ItemProperty $_.PSPath } |
155+
Where-Object { $_.DisplayName -match "Python 3\.11\.9" } |
156+
Select-Object -First 1
157+
158+
if (-not $pyReg) {
159+
Write-Host "未检测到 Python 3.11.9,跳过卸载" -ForegroundColor Green
160+
return
161+
}
162+
163+
# 3) 判断卸载方式
164+
if ($pyReg.UninstallString -match '\.exe$') {
165+
$exePath = $pyReg.UninstallString -replace '"', ''
166+
$argList = '/passive', '/norestart' # ← 这里改 /passive
167+
$proc = Start-Process -FilePath $exePath -ArgumentList $argList -Wait -PassThru
168+
} else {
169+
$argList = '/X', $pyReg.PSChildName, '/passive', '/norestart' # ← 这里改 /passive
170+
$proc = Start-Process -FilePath 'msiexec.exe' -ArgumentList $argList -Wait -PassThru
171+
}
172+
173+
# 4) 检查退出码
174+
if ($proc.ExitCode -ne 0) {
175+
Write-Warning "卸载返回码 $($proc.ExitCode),建议重启后再继续"
176+
exit $proc.ExitCode
177+
}
125178

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
179+
# 5) 清理残留目录 & PATH
180+
$pyDir = "C:\Python311"
181+
if (Test-Path $pyDir) { Remove-Item -Recurse -Force $pyDir -ErrorAction SilentlyContinue }
182+
$envPaths = [Environment]::GetEnvironmentVariable("PATH", "Machine") -split ';'
183+
$clean = $envPaths | Where-Object { $_ -notmatch '\\Python311\\?' }
184+
[Environment]::SetEnvironmentVariable("PATH", ($clean -join ';'), "Machine")
185+
186+
Write-Host "Python 3.11.9 卸载完成,可继续安装" -ForegroundColor Green
187+
}
188+
catch {
189+
Write-Warning "卸载异常: $($_.Exception.Message)"
130190
}
131191

132-
Write-Host "运行环境卸载步骤结束,如有残留请手动到「应用和功能」确认。" -ForegroundColor Yellow
192+
# 4) 卸载 Git(EXE/MSI)
193+
try {
194+
$gitReg = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" |
195+
ForEach-Object { Get-ItemProperty $_.PSPath } |
196+
Where-Object { $_.DisplayName -match "Git" } |
197+
Select-Object -First 1
198+
if ($gitReg -and $gitReg.UninstallString) {
199+
Write-Host "卸载 Git ..." -ForegroundColor Green
200+
Start-Process -FilePath $gitReg.UninstallString -ArgumentList "/VERYSILENT", "/NORESTART" -Wait
201+
}
202+
# 清理 PATH
203+
$envPaths = [Environment]::GetEnvironmentVariable("PATH", "Machine") -split ';'
204+
$clean = $envPaths | Where-Object { $_ -notmatch '\\Git\\cmd' -and $_ -notmatch '\\Git\\mingw64' -and $_ -notmatch '\\Git\\usr\\bin' }
205+
[Environment]::SetEnvironmentVariable("PATH", ($clean -join ';'), "Machine")
206+
} catch { Write-Warning "Git 卸载失败: $($_.Exception.Message)" }
207+
208+
Write-Host "运行环境卸载完成!建议重启计算机完成彻底清理。" -ForegroundColor Green
209+
}
210+
211+
# ---------- 8. 清理 PM2 数据 ----------
212+
try {
213+
$pm2Home = "C:\$env:USERNAME\.pm2"
214+
if (Test-Path $pm2Home) {
215+
Write-Host "清理 PM2 数据目录 ..." -ForegroundColor Green
216+
Remove-Item -Recurse -Force $pm2Home -ErrorAction SilentlyContinue
217+
}
218+
} catch {
219+
Write-Warning "清理 PM2 数据失败: $($_.Exception.Message)"
133220
}
134221

135222
# ---------- 9. 完成 ----------
136223
Write-Host "drpys 卸载完成!" -ForegroundColor Green
137-
Write-Host "按任意键退出!!!" -ForegroundColor Green
224+
if ($IncludeEnv) {
225+
Write-Host "已卸载所有运行环境,建议重启计算机。" -ForegroundColor Yellow
226+
}
227+
Write-Host "按任意键退出..." -ForegroundColor Green
138228
Read-Host

0 commit comments

Comments
 (0)