Files
Notes/scripts/launch.js
2026-09-12 14:15:26 +08:00

118 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Notes 启动包装
//
// 主要职责:
// 1. 处理 Windows 控制台编码cp936 → utf-8让中文日志不乱码
// 2. 在 Windows 上以管理员权限运行时切换工作目录到项目根
// (某些路径如 `C:\Windows\System32` 在普通权限下无法读取 electron 二进制)
// 3. 避免被 ELECTRON_RUN_AS_NODE 影响main.js 也会清除,这里是双保险)
//
// 与 Todo List 的 launch.js 逻辑完全一致 —— 它经过实际使用验证。
const path = require('path');
const { spawn } = require('child_process');
const fs = require('fs');
// 防止 ELECTRON_RUN_AS_NODE=1 让我们作为普通 Node 运行
if (process.env.ELECTRON_RUN_AS_NODE) {
console.log('[launch] 清除 ELECTRON_RUN_AS_NODE 环境变量');
delete process.env.ELECTRON_RUN_AS_NODE;
}
// Windows 控制台 UTF-8
if (process.platform === 'win32') {
try {
process.stdout.setDefaultEncoding('utf8');
process.stderr.setDefaultEncoding('utf8');
} catch {
// 某些嵌入式环境下不可用,忽略
}
// 把当前终端的代码页切换到 UTF-8。
// 否则即使我们输出 UTF-8 字节cmd.exe 默认 cp936 会按 GBK 解析成乱码。
// chcp 65001 = UTF-8 code page
try {
require('child_process').execSync('chcp 65001 > nul', {
stdio: 'ignore',
shell: true,
});
} catch {
// chcp 在某些嵌入式终端不可用,忽略
}
}
// 解析 electron 可执行文件路径
function resolveElectronBinary() {
try {
// 优先使用 require('electron') 暴露的二进制路径dev 模式)
const electronPath = require('electron');
if (typeof electronPath === 'string' && fs.existsSync(electronPath)) {
return electronPath;
}
} catch {
// fallthrough
}
// 兜底:尝试常见路径
const candidates = [
path.join(__dirname, '..', 'node_modules', '.bin', process.platform === 'win32' ? 'electron.cmd' : 'electron'),
path.join(__dirname, '..', 'node_modules', 'electron', 'dist', process.platform === 'win32' ? 'electron.exe' : 'electron'),
];
for (const c of candidates) {
if (fs.existsSync(c)) return c;
}
throw new Error('未找到 electron 可执行文件,请先运行 npm install');
}
const electronPath = resolveElectronBinary();
const projectRoot = path.resolve(__dirname, '..');
console.log('[launch] Electron:', electronPath);
console.log('[launch] 项目根目录:', projectRoot);
// 在 Windows 上以管理员权限运行时,当前工作目录可能是 System32
// electron 二进制所在目录可能存在空格或权限问题,统一切换到项目根
if (process.cwd() !== projectRoot) {
try {
process.chdir(projectRoot);
} catch (e) {
// 切换失败只发警告,不要静默吞掉 —— spawn 仍会用 cwd: projectRoot
// 所以这里失败通常不影响 electron 启动,但日志里有必要让用户看到。
console.warn(`[launch] 切换工作目录到 ${projectRoot} 失败:${e.message}`);
}
}
// 传递所有参数给 electron
const args = [projectRoot, ...process.argv.slice(2)];
console.log('[launch] 启动参数:', args.join(' '));
const child = spawn(electronPath, args, {
stdio: 'inherit',
cwd: projectRoot,
env: {
...process.env,
// 确保不会被子进程继承为 Node 模式
ELECTRON_RUN_AS_NODE: undefined,
},
windowsHide: false,
});
child.on('error', (err) => {
console.error('[launch] 启动失败:', err.message);
process.exit(1);
});
child.on('exit', (code, signal) => {
if (signal) {
console.log(`[launch] Electron 被信号终止: ${signal}`);
process.exit(1);
}
process.exit(code ?? 0);
});
// 透传 Ctrl+C
process.on('SIGINT', () => {
child.kill('SIGINT');
});
process.on('SIGTERM', () => {
child.kill('SIGTERM');
});