Окно с индикатором вместо чёрной консоли

Маленькое окно на C#, собирается компилятором из состава Windows: ставить
нечего, зависимостей нет — как и у всего остального в проекте. Запускает
node дочерним процессом, показывает его вывод, прячется в трей, красит
значок по /api/state.

Node теперь уходит вместе с окном: окно держит его stdin, server.mjs при
DEEPSEEK_TRAY=1 слушает close на этой трубе. Job Object не подошёл бы —
он забрал бы с собой и браузер, который человеку нужен.

Окно смотрит на checked, а не только на ready: снимок обновляет сторож,
и без этой проверки окно показывало бы «готов» через секунду после смерти
браузера. Поэтому /api/state отдаёт ещё и watchdogSec.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Alex Cube
2026-08-26 16:47:34 +03:00
co-authored by Claude Opus 5
parent 52de3b91eb
commit 46ea8a9296
6 changed files with 414 additions and 9 deletions
+9 -1
View File
@@ -218,7 +218,7 @@ const server = createServer(async (req, res) => {
...state,
seconds: state.busy && state.since ? Math.round((Date.now() - state.since) / 1000) : 0,
host: cfg.host, port: cfg.port, cdpPort: cfg.cdpPort,
watchdog: !!cfg.watchdog,
watchdog: !!cfg.watchdog, watchdogSec: cfg.watchdogSec,
});
}
@@ -308,4 +308,12 @@ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href)
}
console.log('Остановить — Ctrl+C');
});
// Запущены из окна (tray.cs): оно держит нашу трубу stdin открытой. Труба
// закрылась — окна больше нет, и висеть дальше незачем: раньше закрытая
// консоль оставляла node в памяти. Браузер при этом переживает нас: он
// отдельный процесс и нужен человеку.
if (process.env.DEEPSEEK_TRAY) {
process.stdin.on('close', () => process.exit(0)).resume();
}
}