param( [string]$HostName = "0.0.0.0", [int]$Port = 31106, [switch]$NoKillExisting, [switch]$DryRun ) $ErrorActionPreference = "Stop" function Get-ListeningProcessIds([int]$TargetPort) { $listeners = Get-NetTCPConnection -LocalPort $TargetPort -State Listen -ErrorAction SilentlyContinue if (-not $listeners) { return @() } return ($listeners | Select-Object -ExpandProperty OwningProcess -Unique) } function Stop-ListeningProcesses([int]$TargetPort) { $pids = Get-ListeningProcessIds -TargetPort $TargetPort if (-not $pids -or $pids.Count -eq 0) { Write-Host "[start] port $TargetPort is free." return } foreach ($pidValue in $pids) { $proc = Get-Process -Id $pidValue -ErrorAction SilentlyContinue if ($null -eq $proc) { continue } Write-Host "[start] port $TargetPort is used by PID=$pidValue Name=$($proc.ProcessName)" if ($DryRun) { Write-Host "[start] DryRun: skip stopping PID=$pidValue" continue } Stop-Process -Id $pidValue -Force Write-Host "[start] stopped PID=$pidValue" } Start-Sleep -Milliseconds 400 } function Ensure-PortAvailable([int]$TargetPort) { $pids = Get-ListeningProcessIds -TargetPort $TargetPort if ($pids.Count -gt 0) { throw "port $TargetPort is still occupied, cannot start service." } } $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path Set-Location $scriptDir Write-Host "[start] project dir: $scriptDir" Write-Host "[start] target: http://$HostName`:$Port" if (-not $NoKillExisting) { Stop-ListeningProcesses -TargetPort $Port } else { $existing = Get-ListeningProcessIds -TargetPort $Port if ($existing.Count -gt 0) { throw "port $Port is occupied and -NoKillExisting is set." } } Ensure-PortAvailable -TargetPort $Port if ($DryRun) { Write-Host "[start] DryRun: checks passed, skip launching." exit 0 } Write-Host "[start] launching service..." $env:SURUGAYA_APP_HOST = $HostName $env:SURUGAYA_APP_PORT = "$Port" # python -m app.main uvicorn app.main:app --host $HostName --port $Port