From e12570f9d1aa2645e6bb223b1417fa0e81957b65 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Mon, 14 Sep 2026 23:51:36 +0200 Subject: fix(win): a service-mode daemon can be replaced, and the Node page can link one Two live-reproduced bugs in Windows node start/stop, found sideloading the 0.14.0 build: - node:start's crash-recovery step killed a service-mode daemon with taskkill/CTRL_BREAK, both of which fail with "Access is denied" against a process running under the Scheduled Task's own S4U logon session (a different session from the Electron app's). The daemon it was meant to replace just kept running, unreplaced, and schtasks /run on a task Windows still considered Running was then a silent no-op too. Route through winServiceTaskEnd() (schtasks /end) first, the way nodeServiceStop/ nodeServiceRestart already correctly do. service-mode.ps1 also now starts the task right after registering it -- Register-ScheduledTask's own AtStartup trigger does not run it immediately, so nothing was listening until the next reboot. - The Node page's Start button called node.start() with no arguments, so an unlinked node (a fresh install, or one whose hub-side link was lost) could never link on Start alone -- only create-group-page.js's own call passed {hubUrl, username, token}. Reproduced on a fresh non-service install signed in to the real hub: Start hung for ~105s and failed with "could not link", pointing at a "Link Node" control that lives on Settings, not the Node page (that message is fixed too). Co-Authored-By: Claude Sonnet 5 --- packaging/win/service-mode.ps1 | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'packaging') diff --git a/packaging/win/service-mode.ps1 b/packaging/win/service-mode.ps1 index e522f04..2cb61b4 100644 --- a/packaging/win/service-mode.ps1 +++ b/packaging/win/service-mode.ps1 @@ -19,7 +19,7 @@ one place: %TEMP%\meshbay-firewall.log. .PARAMETER Action - install service.ps1 install, then firewall.ps1 add + install service.ps1 install, then firewall.ps1 add, then service.ps1 run remove service.ps1 remove, then firewall.ps1 remove #> [CmdletBinding()] @@ -51,5 +51,26 @@ catch { $failed = $true } +# Register-ScheduledTask with -Trigger AtStartup does exactly that -- it does +# not launch the task now. Every caller of this script (the installer's own +# "background service" choice, and the Node page's later toggle) expects the +# node to actually be running by the time the one UAC prompt they were shown +# returns; without this, nothing is listening until the next reboot, with no +# error and no indication that anything is still needed. `run` needs no +# further elevation (Task Scheduler grants the owning user that much once the +# task exists) -- doing it here, inside the same elevated pass, is only about +# timing: the daemon comes up before this script's own exit code reaches the +# caller, not because starting it needs the admin token this script is +# holding. A no-op, harmlessly, if the task is already running (2026-09-14). +if ($Action -eq "install" -and -not $failed) { + try { + & (Join-Path $here "service.ps1") "run" + } + catch { + " service run failed: $_" | Add-Content $log + $failed = $true + } +} + if ($failed) { exit 1 } exit 0 -- cgit v1.2.3