import { BrowserWindow, app } from 'electron' import { join } from 'path' import { existsSync, statSync } from 'fs' export function createWindow(): BrowserWindow { const mainWindow = new BrowserWindow({ width: 1200, height: 800, minWidth: 800, minHeight: 600, icon: join(__dirname, '../assets/icon.ico'), webPreferences: { preload: join(__dirname, '../preload/index.js'), contextIsolation: true, nodeIntegration: false, sandbox: true }, titleBarStyle: 'default', show: false }) mainWindow.setMenu(null) // H-04: 阻止窗口导航和弹出窗口,防止渲染进程绕过 CSP mainWindow.webContents.on('will-navigate', (event) => { event.preventDefault() }) mainWindow.webContents.setWindowOpenHandler(() => ({ action: 'deny' })) mainWindow.once('ready-to-show', () => { mainWindow.show() }) return mainWindow } export function setupSingleInstanceLock( onSecondInstance: (filePath: string | null) => void ): boolean { const gotTheLock = app.requestSingleInstanceLock() if (!gotTheLock) { app.quit() return false } app.on('second-instance', (_event, commandLine) => { const filePath = getFilePathFromArgs(commandLine) onSecondInstance(filePath) }) return true } // L-08: 使用静态导入 + 验证是文件而非目录 export function getFilePathFromArgs(args: string[]): string | null { for (let i = 1; i < args.length; i++) { const arg = args[i] if (!arg.startsWith('--') && !arg.startsWith('-')) { try { if (existsSync(arg)) { const s = statSync(arg) if (s.isFile()) return arg } } catch { // ignore } } } return null }