From 0f5e5bf00a5fefdb8ca76ca6ec7c0bd0353374d1 Mon Sep 17 00:00:00 2001 From: sravan Date: Thu, 2 Jul 2026 00:28:43 +0530 Subject: [PATCH] fix(desktop): spawn SnoreToast from app.asar.unpacked (was ENOENT inside asar) snoreExe returned the app.asar path (fs.existsSync lies about asar paths), so spawn failed with ENOENT and always fell back to the reply-less WindowsToaster. Map to app.asar.unpacked unconditionally so the real SnoreToast binary (with -w) runs and captures the reply. Co-Authored-By: Claude Opus 4.8 --- desktop/main.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/desktop/main.js b/desktop/main.js index 6e0fed8..2fe5089 100644 --- a/desktop/main.js +++ b/desktop/main.js @@ -61,10 +61,14 @@ function snoreExe() { try { const dir = path.dirname(require.resolve('node-notifier')); const exe = os.arch() === 'ia32' ? 'snoretoast-x86.exe' : 'snoretoast-x64.exe'; - const base = path.join(dir, 'vendor', 'snoreToast', exe); - for (const c of [base, base.replace('app.asar' + path.sep, 'app.asar.unpacked' + path.sep)]) { - if (fs.existsSync(c)) return c; + let p = path.join(dir, 'vendor', 'snoreToast', exe); + // In a packaged app the module resolves inside app.asar, but binaries live in + // app.asar.unpacked — and fs.existsSync falsely reports the asar path exists, so we can't + // test it; map to the unpacked copy unconditionally (that's the real, spawnable file). + if (p.includes('app.asar' + path.sep) && !p.includes('app.asar.unpacked')) { + p = p.replace('app.asar' + path.sep, 'app.asar.unpacked' + path.sep); } + return p; } catch (_) {} return null; }