feat: auto-updater integration

- Install electron-updater
- New updater.ts: check/download/install with progress events
- IPC: updater:check, updater:download, updater:install, updater:status
- Preload bridge for updater API
- electron-builder publish config (github provider)
- Fix build files path: out -> electron-dist
- i18n keys for updater notifications (zh-CN + en)
This commit is contained in:
2026-07-05 22:13:25 +08:00
parent d131a2732d
commit 405dfa77c4
9 changed files with 163 additions and 11 deletions
+2
View File
@@ -3,6 +3,7 @@ import { app, BrowserWindow, nativeTheme, nativeImage } from 'electron'
import { join } from 'path'
import { restoreAndTrack } from './win-state'
import { registerIpcHandlers } from './ipc-handlers'
import { initUpdater } from './updater'
let mainWindow: BrowserWindow | null = null
@@ -55,6 +56,7 @@ function createWindow(): void {
app.whenReady().then(() => {
registerIpcHandlers()
createWindow()
initUpdater(mainWindow!)
})
app.on('window-all-closed', () => { app.quit() })
+71
View File
@@ -0,0 +1,71 @@
// electron/main/updater.ts
// 自动更新模块
import { autoUpdater } from 'electron-updater'
import { BrowserWindow, ipcMain } from 'electron'
let mainWindow: BrowserWindow | null = null
export function initUpdater(win: BrowserWindow): void {
mainWindow = win
// 检查更新
ipcMain.handle('updater:check', async () => {
try {
const result = await autoUpdater.checkForUpdates()
return result?.updateInfo ? { available: true, version: result.updateInfo.version } : { available: false }
} catch {
return { available: false }
}
})
// 下载更新
ipcMain.handle('updater:download', async () => {
try {
await autoUpdater.downloadUpdate()
return { success: true }
} catch (err: any) {
return { success: false, error: err.message }
}
})
// 安装更新
ipcMain.handle('updater:install', () => {
autoUpdater.quitAndInstall()
})
autoUpdater.autoDownload = false
autoUpdater.on('checking-for-update', () => {
mainWindow?.webContents.send('updater:status', { status: 'checking' })
})
autoUpdater.on('update-available', (info) => {
mainWindow?.webContents.send('updater:status', {
status: 'available',
version: info.version,
releaseNotes: info.releaseNotes,
})
})
autoUpdater.on('update-not-available', () => {
mainWindow?.webContents.send('updater:status', { status: 'not-available' })
})
autoUpdater.on('download-progress', (progress) => {
mainWindow?.webContents.send('updater:status', {
status: 'downloading',
percent: progress.percent,
transferred: progress.transferred,
total: progress.total,
bytesPerSecond: progress.bytesPerSecond,
})
})
autoUpdater.on('update-downloaded', () => {
mainWindow?.webContents.send('updater:status', { status: 'downloaded' })
})
autoUpdater.on('error', (err) => {
mainWindow?.webContents.send('updater:status', { status: 'error', message: err.message })
})
}