@echo off setlocal set "AI_SHUTDOWN_ROOT=%~dp0" powershell -NoProfile -ExecutionPolicy Bypass -Command "$p='%~f0'; $s=Get-Content -LiteralPath $p -Raw; $m=':ps1'; $i=$s.LastIndexOf($m); if ($i -lt 0) { throw 'PowerShell payload marker not found.' }; Invoke-Expression $s.Substring($i + $m.Length)" set "EXIT_CODE=%ERRORLEVEL%" if "%~1"=="--no-pause" exit /b %EXIT_CODE% echo. if not "%EXIT_CODE%"=="0" echo [servers] Shutdown failed with exit code %EXIT_CODE%. pause exit /b %EXIT_CODE% :ps1 $ErrorActionPreference = "Stop" $root = (Resolve-Path -LiteralPath $env:AI_SHUTDOWN_ROOT).Path $ports = @(8000, 8001, 8002, 8003, 5173, 5174) function Write-Step { param([string] $Message) Write-Host "[servers] $Message" } Write-Step "Stopping project server processes." $currentPid = $PID $rootPattern = [regex]::Escape($root) $commandPattern = "uvicorn|ont_platform\.api|crawler_platform\.app\.main|phase[0-9]_app|vite|npm(\.cmd)?\s+run\s+(dev|preview|start)" $matched = Get-CimInstance Win32_Process | Where-Object { if (-not $_.CommandLine) { return $false } if ($_.ProcessId -eq $currentPid) { return $false } $cmd = $_.CommandLine return ($cmd -match $commandPattern) -and ( $cmd -match $rootPattern -or $cmd -match "ontology_platform|ont_platform|crawler_platform" ) } foreach ($proc in $matched) { Write-Step ("Killing process {0} ({1})" -f $proc.ProcessId, $proc.Name) Stop-Process -Id $proc.ProcessId -Force -ErrorAction SilentlyContinue } $listeners = Get-NetTCPConnection -State Listen -ErrorAction SilentlyContinue | Where-Object { $ports -contains $_.LocalPort } | Select-Object -ExpandProperty OwningProcess -Unique foreach ($pidToStop in $listeners) { if ($pidToStop -and $pidToStop -ne $currentPid) { Write-Step ("Killing listener on configured dev port, pid {0}" -f $pidToStop) Stop-Process -Id $pidToStop -Force -ErrorAction SilentlyContinue } } $pidFile = Join-Path $root ".server-logs\server-pids.txt" if (Test-Path -LiteralPath $pidFile) { Remove-Item -LiteralPath $pidFile -Force -ErrorAction SilentlyContinue } Write-Step "Done."