import { app, shell, BrowserWindow, ipcMain, globalShortcut } from 'electron' import path, { join } from 'path' import { electronApp, optimizer, is } from '@electron-toolkit/utils' import icon from '../../resources/earth.png?asset' import fs from 'fs' const { exec } = require('child_process'); // 开发环境路径处理 - 确保添加正确的file协议 const devSplashPath = path.resolve( app.getAppPath(), 'src', 'renderer', 'public', 'startUp', 'startUp.html' ) // 开发环境必须添加file协议,使用URL构造器确保格式正确 const devSplashURL = new URL(`file:///${devSplashPath}`).href // 生产环境路径处理 let prodSplashURL = '' const prodPossiblePaths = [ path.join(process.resourcesPath, 'app.asar', 'out', 'renderer', 'startUp', 'startUp.html'), path.join(process.resourcesPath, 'app.asar', 'renderer', 'startUp', 'startUp.html'), path.join(process.resourcesPath, 'out', 'renderer', 'startUp', 'startUp.html'), // 增加asar包外可能的路径 path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'startUp', 'startUp.html') ] // 寻找存在的生产环境路径 const prodSplashPath = prodPossiblePaths.find((p) => { try { // 检查路径是否存在,处理asar内部文件检查 return fs.existsSync(p) } catch (e: any) { console.error('检查路径时出错:', p, e.message) return false } }) if (prodSplashPath) { // 使用URL构造器处理路径,自动编码特殊字符 // 对于Windows系统,需要处理盘符前的斜杠问题 const normalizedPath = process.platform === 'win32' ? prodSplashPath.replace(/^(\w:)/, '/$1') : prodSplashPath prodSplashURL = new URL(`file://${normalizedPath}`).href } else { console.error('未找到有效的启动页路径,检查打包配置和文件是否存在') // 可以在这里添加默认路径或错误处理 } // 最终的启动页URL const splashURL = process.env.NODE_ENV === 'development' ? devSplashURL : prodSplashURL // const splashURL = // process.env.NODE_ENV === 'development' // ? `${join(app.getAppPath(), 'src/renderer/public/startUp/startUp.html')}` // : `file://${join(app.getAppPath(), 'resources/app.asar/out/renderer/startUp/startUp.html')}` function createWindow(): void { // Create the browser window. // 创建启动窗口 const splashWindow = new BrowserWindow({ width: 896, height: 510, frame: false, alwaysOnTop: true, show: false, webPreferences: { nodeIntegration: true, // 开启 Node 集成 contextIsolation: false, // 关闭上下文隔离 devTools: true, webSecurity: false, allowRunningInsecureContent: true } }) // 显示启动页 splashWindow.loadURL(splashURL) splashWindow.show() // 创建主窗口(保持原有配置,但先不显示) const mainWindow = new BrowserWindow({ minWidth: 1780, // 添加最小宽度限制 minHeight: 920, // 添加最小高度限制 // fullscreen: true, show: false, frame: true, autoHideMenuBar: true, useContentSize: true, // 窗口尺寸包含内容区域而非边框 simpleFullscreen: true, // 使用简单全屏模式(仅macOS有效) backgroundColor: '#00000000', // 添加这行设置透明背景 ...(process.platform === 'linux' ? { icon } : {}), webPreferences: { preload: join(__dirname, '../preload/index.js'), sandbox: false, nodeIntegration: true, // 开启 Node 集成 contextIsolation: false, // 关闭上下文隔离 devTools: true, webSecurity: false, allowRunningInsecureContent: true } }) // 监听启动页完成的消息 ipcMain.on('splash-completed', () => { // 启动页进度条已完成,可以关闭启动页并显示主窗口 setTimeout(() => { splashWindow.destroy() mainWindow.maximize() // 先最大化 mainWindow.show() setTimeout(() => { mainWindow.webContents.send('start-login-video') }, 200) // 给一点时间让窗口完全显示 }, 1000) }) ipcMain.on('quit-app', () => { app.quit() }) ipcMain.on('renderNode', () => { // 获取所有窗口并转发消息 BrowserWindow.getAllWindows().forEach((win) => { // 移除条件判断,确保所有窗口都能收到消息 setTimeout(() => { win.webContents.send('renderNode-reply') }, 200) }) }) // 设置窗口标题和图标 mainWindow.webContents.setWindowOpenHandler((details) => { shell.openExternal(details.url) return { action: 'deny' } }) // 注册 F5 快捷键刷新 globalShortcut.register('CommandOrControl+F5', () => { if (mainWindow) { mainWindow.reload() setTimeout(() => { mainWindow.webContents.send('start-login-video') }, 200) // 给一点时间让窗口完成刷新 } }) globalShortcut.register('CommandOrControl+F12', () => { mainWindow.webContents.openDevTools() }) // HMR for renderer base on electron-vite cli. // Load the remote URL for development or the local html file for production. if (is.dev && process.env['ELECTRON_RENDERER_URL']) { mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) } else { mainWindow.loadFile(join(__dirname, '../renderer/index.html')) } } // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.whenReady().then(() => { // Set app user model id for windows electronApp.setAppUserModelId('com.electron') // Default open or close DevTools by F12 in development // and ignore CommandOrControl + R in production. // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils app.on('browser-window-created', (_, window) => { optimizer.watchWindowShortcuts(window) }) // IPC test ipcMain.on('ping', () => console.log('pong')) createWindow() app.on('activate', function () { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) // 退出时注销所有快捷键 app.on('will-quit', () => { globalShortcut.unregisterAll() }) // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here.