引言 在Electron应用程序中,窗口管理和自动更新是两个关键特性,它们对用户体验和应用程序的可靠性至关重要。在本篇文章中,我们将探讨如何在Electron应用程序中有效地管理窗口,以及如何实现自动更新机制。
1. 窗口管理 Electron应用程序通常由多个窗口组成,如主窗口、对话框、弹出窗口、登录窗口等。有效地管理这些窗口对于创建一个流畅的用户界面至关重要。
创建窗口
在Electron中,我们直接使用BrowserWindow
类来创建窗口。你可以设置窗口的各种属性,如大小、位置、图标等,下面是一个简单例子。
javascript
// 主进程中的代码
const { app, BrowserWindow } = require('electron');
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
});
// 加载页面或文件
win.loadFile('index.html');
// 打开开发者工具(如果需要)
// win.webContents.openDevTools();
// 处理窗口关闭事件
win.on('closed', () => {
win = null;
});
}
app.whenReady().then(createWindow);
窗口事件
窗口支持多种事件,如closed
、moved
、resized
等。你可以监听这些事件来响应窗口的各种状态变化。
窗口间通信
窗口之间可以通过ipcMain
和ipcRenderer
进行通信。这允许你在主进程和渲染进程之间,或者在不同渲染进程之间传递数据。
以下是我封装了一个window的示例,用于登录窗口切换主窗口:
javascript
// window.js
import { app, BrowserWindow, globalShortcut, ipcMain } from 'electron'
import { join } from 'path'
import { buildMenu } from './menu'
import { createTray } from './tray'
import icon from '../../resources/icon.png?asset'
import { checkForUpdates } from './updater'
// 快捷键注册
function registryShortcut() {
globalShortcut.register('CommandOrControl+K', () => {
// 获取当前窗口,并注册快捷键
BrowserWindow.getFocusedWindow().webContents.openDevTools()
})
}
let loginWindow
let mainWindow
// 创建窗口的公共方法
function createWindow(config, url) {
const baseConfig = {
show: false,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
webSecurity: false,
// nodeIntegration: true, // 根据需要设置
// contextIsolation: false, // 根据需要设置
devTools: true
}
}
if (process.platform === 'linux') {
baseConfig.icon = icon
}
const finalConfig = { ...baseConfig, ...config }
const win = new BrowserWindow(finalConfig)
if (!app.isPackaged && process.env['ELECTRON_RENDERER_URL']) {
win.loadURL(process.env['ELECTRON_RENDERER_URL'])
} else {
win.loadFile(url)
}
win.once('ready-to-show', () => win.show())
return win
}
// 创建登录窗口
function createLoginWindow() {
loginWindow = createWindow(
{
width: 600,
height: 670,
autoHideMenuBar: true
},
join(__dirname, '../renderer/index.html')
)
// 加载 /login 路由
loginWindow.webContents.on('did-finish-load', () => {
loginWindow.webContents.send('replace', '/login')
})
ipcMain.once('login', () => {
loginWindow.close()
createMainWindow()
})
}
// 创建主窗口
function createMainWindow() {
mainWindow = createWindow(
{
width: 1024,
height: 768,
autoHideMenuBar: false
},
join(__dirname, '../renderer/index.html')
)
ipcMain.once('open-window', () => {
createMainWindow()
})
ipcMain.once('logout', () => {
mainWindow.close()
createLoginWindow()
})
// 检查更新
ipcMain.on('checkUpdate', () => {
checkForUpdates(mainWindow, ipcMain)
})
// 主要用于创建顶部窗口导航栏
buildMenu(mainWindow)
// 托盘
createTray(mainWindow)
}
app.whenReady().then(() => {
createLoginWindow()
// 注册快捷键
if (!app.isPackaged && process.env['ELECTRON_RENDERER_URL']) {
registryShortcut()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createLoginWindow()
}
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
export default {
createLoginWindow,
createMainWindow
}
2. 自动更新
自动更新是保持应用程序最新和安全的常用方法。Electron提供了electron-updater
库来实现自动更新机制。
使用electron-updater
首先,你需要安装electron-updater
库。
bash
npm install electron-updater
然后,在主进程中初始化electron-updater
,并配置更新选项。
javascript
// 主进程中的代码
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
const { autoUpdater } = require('electron-updater');
function createWindow() {
// ...创建窗口的代码
}
app.whenReady().then(createWindow);
// 设置自动更新
autoUpdater.on('update-available', (info) => {
dialog.showMessageBox({
type: 'info',
title: '更新可用',
message: '有新的更新可用,是否下载并安装?',
button: ['是', '否']
}).then((result) => {
if (result.response === 0) {
autoUpdater.downloadUpdate();
}
});
});
autoUpdater.on('update-downloaded', (info) => {
dialog.showMessageBox({
type: 'info',
title: '更新下载完成',
message: '更新已下载,是否重启以安装?',
button: ['是', '否']
}).then((result) => {
if (result.response === 0) {
autoUpdater.quitAndInstall();
}
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
那么, 我们如何在本地调试更新呢?
首先,我们要本地打包一次,我的window系统,所以依次执行
arduino
npm run build
npm run build:win
打包成功后,把dist目录下app-update.yml文件代码复制给根目录app-update.yml,如下图所示
然后,update.js文件增加这串代码
修改version版本(必须比当前版本低)
最后本地运行
arduino
npm run dev