This commit is contained in:
2026-09-12 14:15:26 +08:00
commit 9c06d3f4be
99 changed files with 41853 additions and 0 deletions

117
scripts/launch.js Normal file
View File

@@ -0,0 +1,117 @@
// 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');
});