fix(autostart): hide console window on logon via wscript VBS shim
Run-key autostart used to register node.exe directly, which made Windows pop a console window at every user logon. Now install-autostart writes a one-line WshShell.Run launcher with vbHide and points the Run-key value at wscript.exe, so the daemon starts truly hidden. Uninstall paths also clean the .vbs file. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,7 @@ const SERVICE_NAME = "ClaudeMailbox";
|
|||||||
const RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
|
const RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
|
||||||
const RUN_VALUE = "ClaudeMailbox";
|
const RUN_VALUE = "ClaudeMailbox";
|
||||||
const MARKER_FILE = "autostart-mode";
|
const MARKER_FILE = "autostart-mode";
|
||||||
|
const LAUNCHER_FILE = "autostart-launcher.vbs";
|
||||||
|
|
||||||
function ensureConfigSeeded(opts: AutostartInstallOpts): string {
|
function ensureConfigSeeded(opts: AutostartInstallOpts): string {
|
||||||
const path = userConfigPath();
|
const path = userConfigPath();
|
||||||
@@ -79,9 +80,33 @@ function tryScheduledTaskInstall(opts: AutostartInstallOpts): { ok: boolean; std
|
|||||||
return { ok: true, stderr: "" };
|
return { ok: true, stderr: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function runKeyLauncherPath(): string {
|
||||||
|
return join(dirname(userConfigPath()), LAUNCHER_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeRunKeyLauncher(configPath: string): string {
|
||||||
|
const { node, script } = buildServeCommand();
|
||||||
|
const cmd = `"${node}" "${script}" serve --config "${configPath}"`;
|
||||||
|
const escaped = cmd.replace(/"/g, '""');
|
||||||
|
const vbs =
|
||||||
|
`Set WshShell = CreateObject("WScript.Shell")\r\n` +
|
||||||
|
`WshShell.Run "${escaped}", 0, False\r\n` +
|
||||||
|
`Set WshShell = Nothing\r\n`;
|
||||||
|
const path = runKeyLauncherPath();
|
||||||
|
mkdirSync(dirname(path), { recursive: true });
|
||||||
|
writeFileSync(path, vbs, "utf8");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeRunKeyLauncher(): void {
|
||||||
|
const path = runKeyLauncherPath();
|
||||||
|
if (existsSync(path)) rmSync(path, { force: true });
|
||||||
|
}
|
||||||
|
|
||||||
function runKeyInstall(opts: AutostartInstallOpts): void {
|
function runKeyInstall(opts: AutostartInstallOpts): void {
|
||||||
const configPath = ensureConfigSeeded(opts);
|
const configPath = ensureConfigSeeded(opts);
|
||||||
const cmd = buildServeCommandString(configPath);
|
const launcher = writeRunKeyLauncher(configPath);
|
||||||
|
const cmd = `wscript.exe "${launcher}"`;
|
||||||
const r = run("reg.exe", [
|
const r = run("reg.exe", [
|
||||||
"add",
|
"add",
|
||||||
RUN_KEY,
|
RUN_KEY,
|
||||||
@@ -122,6 +147,7 @@ function runKeyUninstall(): void {
|
|||||||
if (r.status !== 0 && !/unable to find/i.test(r.stderr)) {
|
if (r.status !== 0 && !/unable to find/i.test(r.stderr)) {
|
||||||
throw new Error(`reg delete failed (exit ${r.status}): ${r.stderr || r.stdout}`);
|
throw new Error(`reg delete failed (exit ${r.status}): ${r.stderr || r.stdout}`);
|
||||||
}
|
}
|
||||||
|
removeRunKeyLauncher();
|
||||||
killRunKeyDaemon();
|
killRunKeyDaemon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +184,7 @@ function scheduledTaskUninstall(purge: boolean): void {
|
|||||||
}
|
}
|
||||||
// Best-effort Run-key cleanup
|
// Best-effort Run-key cleanup
|
||||||
run("reg.exe", ["delete", RUN_KEY, "/v", RUN_VALUE, "/f"]);
|
run("reg.exe", ["delete", RUN_KEY, "/v", RUN_VALUE, "/f"]);
|
||||||
|
removeRunKeyLauncher();
|
||||||
killRunKeyDaemon();
|
killRunKeyDaemon();
|
||||||
clearActiveMode();
|
clearActiveMode();
|
||||||
if (purge) purgeData();
|
if (purge) purgeData();
|
||||||
|
|||||||
Reference in New Issue
Block a user