$ErrorActionPreference = "Stop" $projectRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path $runtimeRoot = Join-Path $projectRoot ".runtime" function Stop-OwnedRuntimeProcess { param( [string]$Name, [string]$PidFile ) if (-not (Test-Path -LiteralPath $PidFile)) { Write-Host "$Name is not running." return } $parts = (Get-Content -LiteralPath $PidFile -Raw).Trim().Split("|") $processId = 0 $startTicks = 0L $validIdentity = ( $parts.Count -eq 2 -and [int]::TryParse($parts[0], [ref]$processId) -and [long]::TryParse($parts[1], [ref]$startTicks) ) $process = $null if ($validIdentity) { $process = Get-Process -Id $processId -ErrorAction SilentlyContinue } if ( $null -ne $process -and $process.StartTime.ToUniversalTime().Ticks -eq $startTicks ) { Stop-Process -Id $processId -Force Write-Host "Stopped $Name (PID $processId)." } else { Write-Host "$Name had no matching live process; removed its stale PID file." } Remove-Item -LiteralPath $PidFile -Force } Stop-OwnedRuntimeProcess ` -Name "Feishu events" ` -PidFile (Join-Path $runtimeRoot "feishu-events.pid") Stop-OwnedRuntimeProcess ` -Name "API and embedded scheduler" ` -PidFile (Join-Path $runtimeRoot "api.pid")