170 lines
5.1 KiB
TypeScript
170 lines
5.1 KiB
TypeScript
/**
|
||
* Electron 主进程入口文件
|
||
* 负责创建窗口、管理应用生命周期
|
||
*/
|
||
import { app, BrowserWindow } from 'electron'
|
||
import path from 'path'
|
||
import { setupIpcHandlers } from './ipc'
|
||
import { initStore, getWindowBounds, saveWindowBounds } from './store'
|
||
|
||
// 开发环境下的 Vite 开发服务器地址
|
||
const VITE_DEV_SERVER_URL = process.env['VITE_DEV_SERVER_URL']
|
||
|
||
// 主窗口引用
|
||
let mainWindow: BrowserWindow | null = null
|
||
|
||
/**
|
||
* 创建主窗口
|
||
*/
|
||
function createWindow() {
|
||
// 获取保存的窗口尺寸
|
||
const bounds = getWindowBounds()
|
||
|
||
// 构建窗口配置
|
||
const windowOptions: Electron.BrowserWindowConstructorOptions = {
|
||
width: bounds.width,
|
||
height: bounds.height,
|
||
webPreferences: {
|
||
// 安全配置:启用上下文隔离
|
||
contextIsolation: true,
|
||
// 安全配置:禁用 Node.js 集成
|
||
nodeIntegration: false,
|
||
// 预加载脚本路径
|
||
preload: path.join(__dirname, 'preload.js'),
|
||
// 启用沙盒模式
|
||
sandbox: false // 需要设为 false 才能使用 preload
|
||
},
|
||
// 窗口样式
|
||
title: 'AssetPro',
|
||
show: false, // 先隐藏,等准备好再显示
|
||
backgroundColor: '#ffffff',
|
||
// 无边框窗口
|
||
frame: false
|
||
}
|
||
|
||
// 如果有保存的位置,使用保存的位置;否则居中显示
|
||
if (bounds.x !== undefined && bounds.y !== undefined) {
|
||
windowOptions.x = bounds.x
|
||
windowOptions.y = bounds.y
|
||
} else {
|
||
windowOptions.center = true // 居中显示
|
||
}
|
||
|
||
mainWindow = new BrowserWindow(windowOptions)
|
||
|
||
// 窗口准备好后显示
|
||
mainWindow.once('ready-to-show', () => {
|
||
mainWindow?.show()
|
||
})
|
||
|
||
// 如果 3 秒后还没显示,强制显示窗口(防止页面加载失败导致窗口不显示)
|
||
setTimeout(() => {
|
||
if (mainWindow && !mainWindow.isVisible()) {
|
||
console.log('超时后强制显示窗口')
|
||
mainWindow.show()
|
||
}
|
||
}, 3000)
|
||
|
||
// 监听窗口关闭事件,保存窗口位置和大小
|
||
mainWindow.on('close', () => {
|
||
if (mainWindow) {
|
||
const bounds = mainWindow.getBounds()
|
||
saveWindowBounds(bounds)
|
||
}
|
||
})
|
||
|
||
// 加载页面
|
||
if (VITE_DEV_SERVER_URL) {
|
||
// 开发环境:加载 Vite 开发服务器
|
||
mainWindow.loadURL(VITE_DEV_SERVER_URL)
|
||
// 开发者工具默认关闭,可按 F12 手动打开
|
||
} else {
|
||
// 生产环境:加载打包后的文件
|
||
const fs = require('fs')
|
||
|
||
// dist-renderer 被打包到 asar 中,从 asar 内部加载
|
||
const possiblePaths = [
|
||
path.join(app.getAppPath(), 'dist-renderer', 'index.html'), // asar 内部(主要路径)
|
||
path.join(process.resourcesPath, 'dist-renderer', 'index.html'), // resources/dist-renderer(如果 extraResources 存在)
|
||
path.join(process.resourcesPath, 'dist', 'index.html'), // resources/dist(备用)
|
||
]
|
||
|
||
console.log('尝试加载页面,检查以下路径:')
|
||
possiblePaths.forEach(p => {
|
||
const exists = fs.existsSync(p)
|
||
console.log(` ${exists ? '✓' : '✗'} ${p}`)
|
||
})
|
||
console.log('process.resourcesPath:', process.resourcesPath)
|
||
console.log('app.getAppPath():', app.getAppPath())
|
||
|
||
let indexPath: string | null = null
|
||
for (const testPath of possiblePaths) {
|
||
if (fs.existsSync(testPath)) {
|
||
indexPath = testPath
|
||
console.log('找到页面文件:', indexPath)
|
||
break
|
||
}
|
||
}
|
||
|
||
if (!indexPath) {
|
||
console.error('无法找到 index.html 文件!')
|
||
// 显示一个错误页面
|
||
mainWindow.loadURL('data:text/html,<h1>无法找到页面文件</h1><p>请检查控制台输出</p>')
|
||
return
|
||
}
|
||
|
||
// 使用 loadFile 加载文件
|
||
mainWindow.loadFile(indexPath).catch((error) => {
|
||
console.error('loadFile 失败:', error)
|
||
// 如果 loadFile 失败,尝试使用 loadURL
|
||
// Windows 路径需要特殊处理
|
||
let fileUrl = indexPath.replace(/\\/g, '/')
|
||
if (fileUrl.match(/^[A-Z]:/)) {
|
||
fileUrl = `file:///${fileUrl}`
|
||
} else {
|
||
fileUrl = `file://${fileUrl}`
|
||
}
|
||
console.log('尝试使用 loadURL:', fileUrl)
|
||
mainWindow.loadURL(fileUrl).catch((urlError) => {
|
||
console.error('loadURL 也失败:', urlError)
|
||
// 显示错误页面
|
||
mainWindow.loadURL('data:text/html,<h1>页面加载失败</h1><p>请查看控制台错误信息</p>')
|
||
})
|
||
})
|
||
}
|
||
|
||
// 监听页面加载错误
|
||
mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => {
|
||
console.error('页面加载失败:', errorCode, errorDescription)
|
||
// 开发者工具默认关闭,可按 F12 手动打开
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 应用初始化
|
||
*/
|
||
app.whenReady().then(() => {
|
||
// 初始化 electron-store
|
||
initStore()
|
||
|
||
// 设置 IPC 处理器
|
||
setupIpcHandlers()
|
||
|
||
// 创建窗口
|
||
createWindow()
|
||
|
||
// macOS 特殊处理:点击 dock 图标时重新创建窗口
|
||
app.on('activate', () => {
|
||
if (BrowserWindow.getAllWindows().length === 0) {
|
||
createWindow()
|
||
}
|
||
})
|
||
})
|
||
|
||
// 所有窗口关闭时退出应用(macOS 除外)
|
||
app.on('window-all-closed', () => {
|
||
if (process.platform !== 'darwin') {
|
||
app.quit()
|
||
}
|
||
})
|