diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-04 09:28:14 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-04 09:28:14 +0200 |
| commit | 3ce52774760b222d94d78bc0118e9da2662a809f (patch) | |
| tree | 52a16c7e05080869fbb17b83665b2fb2048b21e2 /packages/meshbay-client | |
| parent | 220e6e701806213a576ce80fa655cd9cf4a51880 (diff) | |
| download | meshbay-3ce52774760b222d94d78bc0118e9da2662a809f.tar.gz | |
feat: Windows installer (W4) — one per-user NSIS package, client + node
`npm run dist:win` produces MeshBay-Setup-<version>.exe: the Electron client
and, beside it under resources/node-runtime/, the frozen meshbay-node daemon
(meshbay-common inside it). No hub. Per-user, no elevation — matches the W3
constraint that a logon-triggered scheduled task needs admin.
electron-builder / package.json
build.win nsis, build/icon.ico, extraResources -> node-runtime/
build.nsis oneClick:false perMachine:false allowElevation:false
allowToChangeInstallationDirectory:true
dist:win -> packaging/win/build-win.ps1 (mirrors dist -> build-client.sh)
packaging/win/
meshbay-node.spec + node-entry.py PyInstaller freeze of
meshbay_node.daemon:main. The awkward deps (aiortc, av, aioquic,
pydantic_core, uvicorn, watchdog, guessit, blake3, tzdata) are pulled
in whole with collect_all — that list is expected to grow when a frozen
run raises ModuleNotFoundError.
build-node-runtime.ps1 throwaway venv -> pip install -> PyInstaller ->
packages/meshbay-client/node-runtime/ (gitignored)
build-win.ps1 Node>=22 check, npm ci, Electron bump, sync-ui,
node runtime, electron-builder --win nsis
bump-electron.mjs the Chromium-CVE "build against latest Electron"
policy, out of the PS script (5.1 here-string terminator rules)
README.md
PyInstaller, not the python-embed zip: the frozen meshbay-node.exe is a
genuine relocatable single binary, which is what src/main.js:findNodeBinary
spawns (process.resourcesPath/node-runtime/meshbay-node.exe when packaged) and
what the W3 autostart launcher points at. The embeddable zip needs pip to make
that wrapper and the wrapper bakes in an absolute interpreter path.
build/installer.nsh: on uninstall, taskkill meshbay-node.exe and delete the W3
Startup .vbs (it would point wscript at a deleted binary every sign-in).
%LOCALAPPDATA%\meshbay\ — node.toml, keystore.enc — is never touched.
ffmpeg is not bundled by default (node finds it on PATH); build-win.ps1
-FfmpegDir copies ffmpeg.exe/ffprobe.exe in for a self-contained installer.
Verified on the Windows guest: PyInstaller freeze builds first try
(node-runtime 147 MB), frozen `meshbay-node status` talks to the live daemon's
loopback API; electron-builder --win nsis produces MeshBay-Setup-0.1.0.exe
(155 MB), oneClick/perMachine flags applied, node-runtime bundled at the path
findNodeBinary expects. test_packaging_win.py (14) pins the config invariants
and the NSIS <-> platform.py autostart seam. Node suite 798 pass / 34 skip.
Open: Authenticode signing (13.9 — unsigned => SmartScreen), Windows CI
(18.3), electron-updater. First clean-machine install + DPAPI + autostart
round-trip is a manual check.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-client')
| -rw-r--r-- | packages/meshbay-client/build/icon.ico | bin | 0 -> 117250 bytes | |||
| -rw-r--r-- | packages/meshbay-client/build/installer.nsh | 24 | ||||
| -rw-r--r-- | packages/meshbay-client/package.json | 27 | ||||
| -rw-r--r-- | packages/meshbay-client/src/main.js | 10 |
4 files changed, 58 insertions, 3 deletions
diff --git a/packages/meshbay-client/build/icon.ico b/packages/meshbay-client/build/icon.ico Binary files differnew file mode 100644 index 0000000..2766f24 --- /dev/null +++ b/packages/meshbay-client/build/icon.ico diff --git a/packages/meshbay-client/build/installer.nsh b/packages/meshbay-client/build/installer.nsh new file mode 100644 index 0000000..cf8e5ff --- /dev/null +++ b/packages/meshbay-client/build/installer.nsh @@ -0,0 +1,24 @@ +; electron-builder NSIS customisation (auto-included: build/installer.nsh). +; +; Per-user install, no elevation (package.json build.nsis). These macros only +; deal with the one piece of state that lives outside the install directory: +; the W3 "run at sign-in" launcher the node's own CLI can create. +; +; Deliberately NOT touched here: +; - %LOCALAPPDATA%\meshbay\ (node.toml, keystore.enc, unlock.key, data/) -- +; the keystore must survive an uninstall/reinstall; installers place files, +; never remove secrets. + +!macro customInstall + ; resources\node-runtime\meshbay-node.exe is overwritten by this install; a + ; daemon still running from a previous version holds the file open. + nsExec::Exec 'taskkill /IM meshbay-node.exe /F' +!macroend + +!macro customUnInstall + nsExec::Exec 'taskkill /IM meshbay-node.exe /F' + ; meshbay_node.platform._startup_vbs() -- if the user ran "meshbay-node + ; autostart install" (or toggled it in the client), this points wscript at + ; the binary we are about to delete, and would error at every sign-in. + Delete "$APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\MeshBay Node.vbs" +!macroend diff --git a/packages/meshbay-client/package.json b/packages/meshbay-client/package.json index 42af9c5..57acff8 100644 --- a/packages/meshbay-client/package.json +++ b/packages/meshbay-client/package.json @@ -10,7 +10,8 @@ "scripts": { "start": "electron .", "sync-ui": "node scripts/sync-ui.js", - "dist": "bash ../../packaging/build/build-client.sh" + "dist": "bash ../../packaging/build/build-client.sh", + "dist:win": "powershell -NoProfile -ExecutionPolicy Bypass -File ../../packaging/win/build-win.ps1" }, "devDependencies": { "electron": "^44.1.1", @@ -22,7 +23,29 @@ "files": [ "src/**", "ui/**" - ] + ], + "win": { + "target": "nsis", + "icon": "build/icon.ico", + "artifactName": "${productName}-Setup-${version}.${ext}", + "extraResources": [ + { + "from": "node-runtime", + "to": "node-runtime", + "filter": ["**/*"] + } + ] + }, + "nsis": { + "oneClick": false, + "perMachine": false, + "allowElevation": false, + "allowToChangeInstallationDirectory": true, + "createDesktopShortcut": true, + "createStartMenuShortcut": true, + "deleteAppDataOnUninstall": false, + "runAfterFinish": true + } }, "dependencies": { "bonjour-service": "^1.4.4", diff --git a/packages/meshbay-client/src/main.js b/packages/meshbay-client/src/main.js index d341619..bd82342 100644 --- a/packages/meshbay-client/src/main.js +++ b/packages/meshbay-client/src/main.js @@ -792,7 +792,15 @@ function registerBridge() { }); function findNodeBinary() { - if (process.platform !== 'win32') { + if (process.platform === 'win32') { + // A packaged Windows build carries the frozen daemon as an + // extraResource (package.json build.win, packaging/win/). Prefer it — + // it is the version that shipped with this client. + if (app.isPackaged) { + const bundled = path.join(process.resourcesPath, 'node-runtime', 'meshbay-node.exe'); + if (fs.existsSync(bundled)) return bundled; + } + } else { const local = path.join(os.homedir(), '.local', 'bin', 'meshbay-node'); if (fs.existsSync(local)) return local; } |