aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-client/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-client/src')
-rw-r--r--packages/meshbay-client/src/main.js52
1 files changed, 46 insertions, 6 deletions
diff --git a/packages/meshbay-client/src/main.js b/packages/meshbay-client/src/main.js
index dd7f38e..e996829 100644
--- a/packages/meshbay-client/src/main.js
+++ b/packages/meshbay-client/src/main.js
@@ -813,7 +813,16 @@ function registerBridge() {
const cmd = process.platform === 'win32' ? 'where.exe' : 'which';
return new Promise((resolve) => {
execFile(cmd, ['meshbay-node'], (err, stdout) => {
- resolve(err ? null : stdout.trim().split('\n')[0]);
+ if (err) { resolve(null); return; }
+ // where.exe/which can list more than one match on PATH, and each
+ // line keeps its own trailing \r on Windows -- `stdout.trim()` only
+ // strips the ends of the *whole* string, so with 2+ matches a stray
+ // \r stayed glued to the end of the first line. That \r then landed
+ // inside the quoted path this function's caller writes into the
+ // Startup .vbs, breaking VBScript's parser with "Unterminated
+ // string constant" the next time Windows tried to run it at sign-in.
+ const first = stdout.split(/\r?\n/).map((s) => s.trim()).find(Boolean);
+ resolve(first || null);
});
});
}
@@ -844,9 +853,24 @@ function registerBridge() {
try { fs.rmSync(WIN_STARTUP_VBS, { force: true }); } catch { /* not there */ }
}
- function killNodeProcesses() {
+ // Prefers a graceful stop: `autostart stop` now tries CTRL_BREAK_EVENT
+ // against the pid autostart_run() recorded first (meshbay_node.platform.
+ // autostart_end()), which daemon.py's SIGBREAK handler turns into a real
+ // _shutdown() -- closed WebRTC sessions, killed ffmpeg -- before that same
+ // function falls back to a hard `taskkill /F` itself. Keeping the
+ // graceful-then-forceful logic in that one place, rather than this
+ // function *also* going straight to taskkill, is what actually fixed it:
+ // two independent hard-kill call sites would still bypass shutdown one of
+ // the times. Only genuinely falls back to taskkill here when the binary
+ // cannot even be located.
+ async function killNodeProcesses() {
+ const bin = await findNodeBinary();
return new Promise((resolve) => {
- execFile('taskkill', ['/IM', 'meshbay-node.exe', '/F'], () => resolve());
+ if (bin) {
+ execFile(bin, ['autostart', 'stop'], () => resolve());
+ } else {
+ execFile('taskkill', ['/IM', 'meshbay-node.exe', '/F'], () => resolve());
+ }
});
}
@@ -897,7 +921,16 @@ function registerBridge() {
return new Promise((resolve, reject) => {
const script = path.join(process.resourcesPath, 'service-mode.ps1');
if (!fs.existsSync(script)) {
- reject(new Error('service-mode.ps1 not found — only available in an installed build'));
+ // service-mode.ps1 is an extraResource -- only present once installed
+ // (package.json build.win.extraResources); nothing under `npm start`.
+ // The Node page already disables the "background service" option
+ // when node:service-status reports canElevate: false, so this should
+ // only ever be reached if that guard is bypassed somehow -- keep the
+ // message actionable regardless.
+ reject(new Error(
+ 'Switching to a background service needs an installed build. For '
+ + 'local testing, run "meshbay-node service install" from an '
+ + 'elevated PowerShell instead.'));
return;
}
// Start-Process -Verb RunAs is the one UAC prompt; -Wait -PassThru hands
@@ -992,6 +1025,12 @@ function registerBridge() {
installed: true,
activeState: running ? 'active' : 'inactive',
subState: svc.state,
+ // Whether switching startup mode can actually elevate right now —
+ // service-mode.ps1 is an extraResource, only present in a packaged
+ // build. Already installed here, so removing it always works
+ // regardless; this only gates the Node page offering to switch
+ // *into* service mode.
+ canElevate: app.isPackaged,
};
}
// Per-user Startup mode. `installed` used to be winAutostartInstalled(),
@@ -1008,6 +1047,7 @@ function registerBridge() {
autostart: winAutostartInstalled(),
activeState: p ? 'active' : 'inactive',
subState: p ? 'running' : '',
+ canElevate: app.isPackaged,
};
}
if (process.platform !== 'linux') return { supported: false };
@@ -1038,8 +1078,8 @@ function registerBridge() {
if (process.platform === 'win32') {
const svc = await winServiceTaskStatus();
if (svc.installed) await winServiceTaskEnd();
- await killNodeProcesses(); // hard kill — no CTRL_CLOSE handler yet;
- // also the belt-and-suspenders in case /end left the process running
+ await killNodeProcesses(); // graceful-then-forceful; also the
+ // belt-and-suspenders in case /end left the process running
return { stopped: true };
}
if (process.platform !== 'linux') {