Electron-updater报错:TypeError: 无法读取undefined的'setClosable'属性
Electron更新失败问题排查与修复
核心问题分析
win变量未初始化就被调用:在update-available事件的回调里,win.setClosable(false)写在了dialog.showMessageBox的回调外部。此时用户还没点击"Ok",createDefaultWindow()还未执行,win仍是undefined,直接调用其方法触发TypeError。- 未校验
win是否存在:error、download-progress等事件处理中,直接使用win.webContents或win的方法,但未先判断win是否已创建,引发连锁报错。
修复后的完整代码
const electron = require('electron') const path = require('path') const {app, dialog, BrowserWindow, ipcMain} = electron const log = require('electron-log') const {autoUpdater} = require('electron-updater') let win; autoUpdater.autoDownload = false autoUpdater.logger = log autoUpdater.logger.transports.file.level = 'info' autoUpdater.setFeedURL({ provider: 'github', token: '', owner: '', repo: '', vPrefixedTagName: true, private: true }) const dispatch = (data) => { // 先校验win是否存在,避免webContents报错 if (win?.webContents) { win.webContents.send('message', data) } } const createDefaultWindow = () => { win = new BrowserWindow({ icon: path.join(__dirname, '/resources/icons/logo.png'), width:600, height: 300 }) win.on('closed', () => { win = null }) win.setMenu(null); win.setClosable(false); win.loadFile('electronMessage/index.html') return win } app.on('ready', () => { log.info('controllando se ci sono aggiornamenti..') autoUpdater.checkForUpdates() }) app.on('window-all-closed', () => { app.quit() }) autoUpdater.on('update-available', (info) => { dialog.showMessageBox({ type: 'info', title: 'Sono disponibili nuovi aggiornamenti', message: 'L\'applicazione verrà aggiornata in automatico.', buttons: ['Ok'] }, (buttonIndex) => { if (buttonIndex === 0) { createDefaultWindow() // 将setClosable移到窗口创建后 win.setClosable(false); win.webContents.on('did-finish-load', () => { win.webContents.send('version', app.getVersion()) }) autoUpdater.downloadUpdate() } }) }) autoUpdater.on('error', (err) => { log.info('errore durante gli aggiornamenti..') dispatch('Si è verificato un errore durante il download degli aggiornamenti: ' + err); // 校验win是否存在再调用方法 if (win) { win.setClosable(true); } }) autoUpdater.on('download-progress', (progressObj) => { // 先判断win是否存在 if (!win) return; let log_message =''; log_message = log_message + "Velocita\' scaricamento: " + progressObj.bytesPerSecond; log_message = log_message + ' - Scaricati ' + progressObj.transferred + " di " + progressObj.total + '\n'; let infoLoad = Math.round(progressObj.percent) + '%'; win.webContents.send('info-speed', log_message) win.webContents.send('info-load', infoLoad) win.webContents.send('download-progress', progressObj.percent) win.setProgressBar(progressObj.percent); }) autoUpdater.on('update-downloaded', (info) => { log.info('aggiornamenti scaricati..') // 校验win是否存在 if (win) { win.setClosable(true); win.close(); } dialog.showMessageBox({ type: 'info', title: 'Installazione', message: 'Aggiornamenti scaricati, l\'applicazione verrà riavviata...', buttons: ['Ok'] }, (buttonIndex) => { if (buttonIndex === 0) { setImmediate(() => { app.removeAllListeners("window-all-closed") autoUpdater.quitAndInstall(false) }) } }) })
关键修改说明
- 把
update-available事件中的win.setClosable(false)移到createDefaultWindow()执行后的回调内部,确保win已初始化。 - 在所有使用
win或win.webContents的位置添加存在性校验,避免undefined报错。 - 优化
dispatch函数,增加win的存在性判断,防止错误扩散。
内容的提问来源于stack exchange,提问作者Jean
相关产品推荐
相关产品推荐

