You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron-updater报错:TypeError: 无法读取undefined的'setClosable'属性

Electron更新失败问题排查与修复

核心问题分析

  1. win变量未初始化就被调用:在update-available事件的回调里,win.setClosable(false)写在了dialog.showMessageBox的回调外部。此时用户还没点击"Ok",createDefaultWindow()还未执行,win仍是undefined,直接调用其方法触发TypeError。
  2. 未校验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)
      })
    }
  })
})

关键修改说明

  1. 把update-available事件中的win.setClosable(false)移到createDefaultWindow()执行后的回调内部,确保win已初始化。
  2. 在所有使用win或win.webContents的位置添加存在性校验,避免undefined报错。
  3. 优化dispatch函数,增加win的存在性判断,防止错误扩散。

内容的提问来源于stack exchange,提问作者Jean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 18:53:15