Fix Windows service mode: it could neither start nor stop.

- Start: WinSW's NetX.out.log/err.log in data\runtime are the same files as
  start_netx.ps1's netx.out.log (case-insensitive) and stay open, so NetX
  could not truncate its log and every start failed. WinSW logs now go to
  data\runtime\service.
- Stop: nothing told the service_run.ps1 supervisor to exit, so it kept
  restarting NetX and WinSW waited forever. stop_netx_app.ps1 writes the
  service.stop flag (-KeepSupervisor for the supervisor's own restarts),
  service_run checks it every second, and runtime_ctl / service_lifecycle
  write it before stopping the service.
- WinSW launched powershell.exe as stop hook never reached the script
  (stuck on inherited std handles); run it via cmd with NUL stdin and output
  to data\runtime\service\stopexec.log. stop_netx_app.ps1 keeps a
  timestamped trace there.

Offline Windows Sandbox: service install -> healthy in 28s, stop in 20s.
Existing service installs need "install service" re-run to pick this up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
oliver 2026-10-14 00:46:44 +08:00
parent c8806c38bd
commit a7cc1f502b
4 changed files with 53 additions and 9 deletions

View file

@ -32,6 +32,7 @@ function Stop-NetxRunners([switch]$Remove) {
$state | ConvertTo-Json | Set-Content -LiteralPath $stateFile -Encoding utf8
if ($svc.Status -ne 'Stopped') {
Write-LifecycleLog 'Stopping Windows service NetX'
Write-NetxServiceStopFlag -DataRoot $data
Stop-Service -Name 'NetX' -Force -ErrorAction Stop
(Get-Service -Name 'NetX').WaitForStatus('Stopped', [TimeSpan]::FromSeconds(60))
}