83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import { getChromePath } from './getChromePath';
|
|
import { getProfileDir } from './getProfileDir';
|
|
import { isPortInUse } from './isPortInUse';
|
|
import { isChromeRunning } from './isChromeRunning';
|
|
import { spawn } from 'child_process';
|
|
import log from 'electron-log';
|
|
|
|
const CHROME_CDP_PORT = 9222;
|
|
const CHROME_READY_TIMEOUT_MS = 15_000;
|
|
const CHROME_READY_POLL_MS = 250;
|
|
|
|
function sleep(ms: number): Promise<void> {
|
|
return new Promise((resolve) => {
|
|
setTimeout(resolve, ms);
|
|
});
|
|
}
|
|
|
|
async function waitForChromeReady(timeoutMs = CHROME_READY_TIMEOUT_MS): Promise<boolean> {
|
|
const startedAt = Date.now();
|
|
|
|
while (Date.now() - startedAt < timeoutMs) {
|
|
if (await isChromeRunning()) {
|
|
return true;
|
|
}
|
|
await sleep(CHROME_READY_POLL_MS);
|
|
}
|
|
|
|
return await isChromeRunning();
|
|
}
|
|
|
|
// 启动本地浏览器
|
|
export async function launchLocalChrome() {
|
|
const chromePath = getChromePath();
|
|
if (!chromePath) {
|
|
throw new Error(`Unsupported platform for Chrome launch: ${process.platform}`);
|
|
}
|
|
|
|
// 多账号隔离
|
|
const profileDir = getProfileDir('default');
|
|
log.info(`Launching Chrome with user data dir: ${profileDir}`);
|
|
|
|
// 检查端口是否被占用
|
|
const portInUse = await isPortInUse(CHROME_CDP_PORT);
|
|
const chromeReady = await isChromeRunning();
|
|
|
|
if (chromeReady) {
|
|
log.info('Chrome DevTools endpoint already available, skip launching.');
|
|
return;
|
|
}
|
|
|
|
if (portInUse) {
|
|
throw new Error(`Port ${CHROME_CDP_PORT} is already in use, but Chrome DevTools is unavailable`);
|
|
}
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
const chromeProcess = spawn(chromePath as string, [
|
|
`--remote-debugging-port=${CHROME_CDP_PORT}`,
|
|
'--window-size=1920,1080',
|
|
'--window-position=0,0',
|
|
'--no-first-run',
|
|
`--user-data-dir=${profileDir}`,
|
|
'--no-default-browser-check',
|
|
'about:blank'
|
|
// '--window-maximized',
|
|
], {
|
|
detached: true,
|
|
stdio: 'ignore',
|
|
});
|
|
|
|
chromeProcess.on('error', (error) => {
|
|
reject(new Error(`Failed to launch Chrome at ${chromePath}: ${error instanceof Error ? error.message : String(error)}`));
|
|
});
|
|
|
|
chromeProcess.unref();
|
|
resolve();
|
|
});
|
|
|
|
const ready = await waitForChromeReady();
|
|
if (!ready) {
|
|
throw new Error(`Chrome launched but DevTools endpoint http://127.0.0.1:${CHROME_CDP_PORT} was not ready within ${CHROME_READY_TIMEOUT_MS}ms`);
|
|
}
|
|
}
|