<#
|
一键停止前后端(与 start-dev.ps1 配套)
|
用法:powershell -NoProfile -ExecutionPolicy Bypass -File stop-dev.ps1
|
|
说明:
|
- 只停本项目相关进程:cmd.exe /c mvn.cmd ... spring-boot:run、cmd.exe /c npm.cmd run serve,
|
以及它们的子进程(java / node / vue-cli-service),按进程树 taskkill /T /F;
|
- 兜底再按命令行特征精确匹配 java(TrafficAuditApplication) 与 node(vue-cli-service) 的孤儿进程;
|
- 不碰其它 node/java 进程(例如 Codex 的 node_repl)与用户自己开的 cmd 窗口;
|
- 结束后检查 8090/8080 是否已释放。
|
#>
|
$ErrorActionPreference = 'Continue'
|
|
function Test-PortListening($port) {
|
try { return [bool](Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction Stop) }
|
catch { return $false }
|
}
|
|
function Stop-Tree($label, $procId) {
|
Write-Host ("{0}:停止进程树 PID={1}" -f $label, $procId)
|
& taskkill.exe /T /F /PID $procId 2>&1 | ForEach-Object { if ($_ -and $_ -notmatch '^SUCCESS') { " $_" } }
|
}
|
|
# ---------- 1) 按「启动用的 cmd 父进程」整树结束 ----------
|
$roots = @(
|
@{ Label = '后端'; Pattern = 'spring-boot:run' },
|
@{ Label = '前端'; Pattern = 'npm.cmd run serve' }
|
)
|
$found = $false
|
$cmdProcs = Get-CimInstance Win32_Process -Filter "Name='cmd.exe'" -ErrorAction SilentlyContinue
|
foreach ($r in $roots) {
|
$hits = @($cmdProcs | Where-Object { $_.CommandLine -and $_.CommandLine -like ('*' + $r.Pattern + '*') })
|
if ($hits.Count -eq 0) { Write-Host ("{0}:未发现启动进程(可能已停止)" -f $r.Label); continue }
|
$found = $true
|
foreach ($h in $hits) { Stop-Tree $r.Label $h.ProcessId }
|
}
|
|
# ---------- 2) 兜底:孤儿 java / node ----------
|
$orphans = @(
|
@{ Label = '后端(java 兜底)'; Name = 'java.exe'; Pattern = 'TrafficAuditApplication' },
|
@{ Label = '前端(node 兜底)'; Name = 'node.exe'; Pattern = 'vue-cli-service' },
|
@{ Label = '前端(inner cmd 兜底)'; Name = 'cmd.exe'; Pattern = 'vue-cli-service serve' }
|
)
|
foreach ($o in $orphans) {
|
$hits = @(Get-CimInstance Win32_Process -Filter ("Name='" + $o.Name + "'") -ErrorAction SilentlyContinue |
|
Where-Object { $_.CommandLine -and $_.CommandLine -like ('*' + $o.Pattern + '*') })
|
foreach ($h in $hits) { $found = $true; Stop-Tree $o.Label $h.ProcessId }
|
}
|
|
if (-not $found) { Write-Host '没有发现需要停止的前后端进程。' }
|
|
# ---------- 3) 校验端口 ----------
|
Start-Sleep -Seconds 4
|
foreach ($port in 8090, 8080) {
|
if (Test-PortListening $port) { Write-Host ("端口 {0}:仍在监听(未完全停止,请重跑一次)" -f $port) }
|
else { Write-Host ("端口 {0}:已释放" -f $port) }
|
}
|