$ErrorActionPreference = 'Stop' function Stop-ListeningPort($port) { try { $lines = netstat -ano | Select-String (":$port ") foreach ($l in $lines) { $m = [regex]::Match($l.ToString(), "\sLISTENING\s+(\d+)$") if ($m.Success) { $procId = [int]$m.Groups[1].Value try { Stop-Process -Id $procId -Force -ErrorAction Stop Write-Host "Stopped PID $procId on port $port" } catch { Write-Host "Failed to stop PID $procId on port ${port}: $($_.Exception.Message)" } } } } catch { Write-Host "Failed to inspect port ${port}: $($_.Exception.Message)" } } $root = Resolve-Path (Join-Path $PSScriptRoot "..\..") $pidsFile = Join-Path $root 'server\.runtime\delivery-backend.pids.json' if (Test-Path $pidsFile) { try { # Windows PowerShell 5.1 + Set-Content -Encoding UTF8 often writes BOM; trim it before JSON parse. $raw = Get-Content -Path $pidsFile -Raw -Encoding UTF8 if ($raw.Length -gt 0 -and $raw[0] -eq [char]0xFEFF) { $raw = $raw.Substring(1) } $pids = $raw | ConvertFrom-Json foreach ($prop in $pids.PSObject.Properties) { $name = $prop.Name $procPid = [int]$prop.Value if ($procPid -gt 0) { try { Stop-Process -Id $procPid -Force -ErrorAction Stop Write-Host "Stopped $name PID=$procPid" } catch { Write-Host "Failed to stop $name PID=${procPid}: $($_.Exception.Message)" } } } try { Remove-Item -Path $pidsFile -Force -ErrorAction Stop Write-Host "Removed pid file: $pidsFile" } catch { Write-Host "Failed to remove pid file: $($_.Exception.Message)" } } catch { Write-Host "Failed to parse ${pidsFile}: $($_.Exception.Message)" } } else { Write-Host "No pid file found: $pidsFile" } # Fallback: ensure ports are freed even if pid file is missing/invalid. Stop-ListeningPort 7201 Stop-ListeningPort 7301