<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packaging/win/service-mode.ps1, branch 0.17</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.17</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.17'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-09-27T20:20:53Z</updated>
<entry>
<title>fix: Windows installer and desktop app start and stop the node one way</title>
<updated>2026-09-27T20:20:53Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-27T20:20:53Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=8c7e39b6dca758badec6867ab6610fd5e8d93d1e'/>
<id>urn:sha1:8c7e39b6dca758badec6867ab6610fd5e8d93d1e</id>
<content type='text'>
A 0.16 upgrade in service mode left the previous node running: setup's
unelevated taskkill cannot reach session 0, and it ran in customInstall, which
electron-builder inserts after the files are copied. The locked exe was not
replaced, and the new app talked to the old node ("started but could not link",
"No operator paired").

Installer (build/installer.nsh, build/stop-node.ps1):
- customCheckAppRunning, which runs before uninstallOldVersion and extraction,
  stops the node with an embedded stop-node.ps1: control API, then schtasks
  /end, then Stop-Process, and refuses to half-upgrade if one survives.
- An upgrade keeps the mode it finds (task, launcher, previous install),
  restores the sign-in launcher the old uninstaller deletes, and restarts the
  node the way that mode runs it. A silent upgrade of an "at sign-in" install
  used to end with no autostart and no node.
- The uninstaller removes the task and firewall rules only on a real
  uninstall, not on an update.

Desktop app (src/main.js):
- Start, Stop, Restart and node:start go through the CLI's lifecycle verbs
  instead of a second implementation; a child spawned by Electron also held
  Electron's sockets after the app quit.
- "Only while MeshBay is open" is a real mode: the app starts a provisioned
  node at launch and stops the one it started when it quits.
- Switching modes stops the node first -- deleting a task does not end its
  instance, and a new service found the port taken -- keeps the firewall
  rules every mode needs, and starts the node again. A declined or unanswered
  UAC prompt restores the node instead of leaving it stopped, and says that
  nothing changed.
- waiting_for_hub counts as a node that is up; linking waits for a node that
  answers, with a longer deadline, and reports a version mismatch.

Packaging (packaging/win):
- The service task gets no 72-hour limit, runs on battery and ignores a second
  start; service.ps1 status reports a stale registration so setup re-registers
  it; remove ends the running instance before deleting the task.
- build-node-runtime.ps1 starts the frozen daemon in a throwaway profile
  (smoke-node-runtime.ps1) instead of only asking for --help.

The mode that was "Off (start manually)" is labelled "Only while MeshBay is
open" in all ten catalogues.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(win): a service-mode daemon can be replaced, and the Node page can link one</title>
<updated>2026-09-14T21:51:36Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-14T21:51:36Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=e12570f9d1aa2645e6bb223b1417fa0e81957b65'/>
<id>urn:sha1:e12570f9d1aa2645e6bb223b1417fa0e81957b65</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: opt-in Windows service mode (boot-time, one elevation) + v1.0.0</title>
<updated>2026-09-04T15:29:24Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-04T15:29:24Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=b78288640d8c13cc0fb3f4ee7c82f3efac33940f'/>
<id>urn:sha1:b78288640d8c13cc0fb3f4ee7c82f3efac33940f</id>
<content type='text'>
The per-user Startup-folder launcher (W3) only ever runs after this user
signs in. A real Windows Service would start earlier, but under
LocalSystem/NetworkService -- accounts with no normal profile, so
%LOCALAPPDATA%\meshbay\ (config, keystore, data) would not exist for it.
Relocating storage to make that work is real surgery, deliberately not
done here.

Instead: a Scheduled Task, created once with admin rights, that runs AS
THIS USER at boot without needing them to sign in first.
`schtasks /create ... /ru &lt;user&gt; /rp ""` with no `/it` registers an S4U
(Service For User) logon -- no password stored anywhere, and unlike
LocalSystem it loads this account's own profile, so config_dir()/
data_dir() need zero changes. The cost: S4U carries no network credential,
which the node never needed -- everything it touches is local disk plus
outbound internet. Creating the task needs admin (a boot trigger touches
system-wide scheduler state, the same reason /sc onlogon needed it);
querying/starting/stopping an existing one does not -- Task Scheduler
grants the owning user that much itself, which is what lets the Node
page's Start/Stop/Restart drive it with no further UAC prompts.

meshbay_node/platform.py
  service_install/_remove/_status/_run/_end -- mirrors autostart_* but
  for the Scheduled Task; TASK_NAME moved here (was decorative before)

meshbay_node/daemon.py
  new `service install|remove|start|stop|status` verb; restart-daemon and
  reset now check for the service task too

packaging/win/service.ps1
  the installer-side equivalent (extraResource); status/run/end never
  self-elevate -- only install/remove do, exactly matching what
  Task Scheduler itself requires

packaging/win/service-mode.ps1
  ONE elevated helper running service.ps1 + firewall.ps1 together, so
  choosing service mode costs exactly one UAC prompt, not two

build/installer.nsh
  the install-time choice: "run as a background service?" (one
  elevation, both jobs) vs the existing per-user + separate firewall
  question. Checked first, unelevated, so re-running setup with
  everything already configured asks nothing. Uninstall offers the
  matching one-elevation cleanup, default No.

src/main.js
  winServiceTaskStatus/Run/End, wired into node:installed,
  node:service-status/-stop/-restart and node:start: when the Scheduled
  Task exists, drive it; otherwise fall back to the existing per-user
  spawn/kill path. This is the hard requirement -- Start/Stop/Restart
  from the Node page must work in either mode.

node-page.js / locales
  a hint explaining why the per-user autostart toggle is absent when
  service mode is active (info.mode from the backend, no new field to
  gate on -- it just isn't sent in that case)

package.json: 0.1.0 -&gt; 1.0.0.

Verified: electron-builder compiles the new NSIS choice logic and ships
all three scripts; service.ps1's S4U install fails cleanly (Access
denied) when run unelevated, and its status/run/end never touch "runas".
Cannot verify the elevated success path myself (no admin in this
session) -- that needs a real UAC click. Node suite 843 pass / 25 skip;
test_packaging_win.py pins the one-elevation property, the S4U flags,
and that main.js actually checks the service task in all three handlers.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
