Electron之单例+多窗口
Electron之单例+多窗口
Electron 24 + React 18
单例可以通过app.requestSingleInstanceLock实现,多窗口可以简单通过路由来实现
单例
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {app.quit();
} else {app.on('second-instance', (event, commandLine, workingDirectory) => {const args = commandLine;const route = args.length > 2 ? args[2] : '';const preWnd = BrowserWindow.getAllWindows().find((e) => e.title === route);if (!preWnd) {createWindow(route);} else {const wnd = BrowserWindow.fromId(preWnd.id);if (wnd) {if (wnd.isMinimized()) {wnd.restore();};wnd.focus();}}});app.whenReady().then(() => {electronApp.setAppUserModelId('electron');app.on('browser-window-created', (_, window) => {optimizer.watchWindowShortcuts(window);});const args = process.argv.splice(app.isPackaged ? 1 : 2);let route = args.length > 0 ? args[0] : 'home';createWindow(route);app.on('activate', function () {if (BrowserWindow.getAllWindows().length === 0) createWindow();});});}
- whenReady时创建初始化窗口
- second-instance时处理重复打开操作
多窗口
const createWindow = (route: string = 'home') => {const windowConfig = getWindowConfig(route);const window = new BrowserWindow({title: windowConfig.title,width: windowConfig.width,height: windowConfig.height,show: false,frame: false,autoHideMenuBar: true,...(process.platform === 'linux' ? { icon } : {}),webPreferences: {preload: join(__dirname, '../preload/index.js'),sandbox: false,devTools: !app.isPackaged,nodeIntegration: true,contextIsolation: false,partition: `persist:${new Date().getTime()}`}});window.on('ready-to-show', () => {window.show();});window.webContents.setWindowOpenHandler((details) => {shell.openExternal(details.url);return { action: 'deny' };});if (is.dev && process.env['ELECTRON_RENDERER_URL']) {window.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/index.html#/${route}`);} else {window.loadFile(join(__dirname, `../renderer/index.html`), { hash: `/${route}` });}return window;
};
<HashRouter><Routes><Route path="/" element={<Home />} /><Route path="/home" element={<Home />} /><Route path="/page1" element={<Page1 />} /></Routes></HashRouter>
- 通过唯一title区分窗口,动态创建新窗口或恢复旧窗口
- 这里前端部分使用react 18 + react-router-dom 6,注意要使用HashRouter