electron -autoUpdater 更新

1.安装依赖: 

npm install electron-updater --save

2.main.js:

1)创建窗口

const {
  app,
  protocol,
  BrowserWindow,
  crashReporter,
  shell,
  Menu,
  ipcMain,
  Tray,
  globalShortcut
} =  require('electron')
// 全局浏览器对象
let win

function createWindow (args = {}) {
  if (win) {
    win.close()
    // win.show()
    // win.focus()
    // win.webContents.send('updateChat', args)
    // return
  }
  win= new BrowserWindow({
    x: 0,
    y: 0,
    resizable: true,
    show: false,
    // titleBarStyle: 'hidden',//是否显示顶部的菜单
    autoHideMenuBar: false,//时候隐藏操作按钮
    useContentSize: true,
    center: false,
    transparent: false,
    webPreferences: {
      nodeIntegration: true,
      nativeWindowOpen: true,
      contextIsolation: false,
      webSecurity: false
    },
    icon: `${__static}/icon/favicon.ico`
  })
  win.loadURL('app://./index.html')


  // 调试模式
  // win.webContents.openDevTools()
  // globalShortcut.register('ctrl+shift+i', function () {
  //   win.webContents.openDevTools() // 打开F12调试页面
  // })

  win.once('ready-to-show', () => {
    win.show()
    win.focus()
    win.webContents.send('updateChat', args)
    if (win.isMaximized()) {
      win.unmaximize()
    } else {
      win.maximize()
    }
  })

  win.on('close', e => {
    win= null
  })
  const menu = Menu.buildFromTemplate([])//自定义菜单
  Menu.setApplicationMenu(menu)
}

2)更新方法

import {autoUpdater} from "electron-updater"
const isDevelopment = process.env.NODE_ENV !== 'production'

/**
 * ipc事件
 */
function ipcEventInit () {
  // 最小化
  ipcMain.on('min', e => win.minimize())
  // 最大化
  ipcMain.on('max', e => {
    if (win.isMaximized()) {
      win.unmaximize()
    } else {
      win.maximize()
    }
  })

  // 关闭
  ipcMain.on('close', e => win.minimize())

  // 执行自动更新检查(通过接口控制,如果接口发现版本号,执行更新)
  //$electron.ipcRenderer.send("checkForUpdate", url)
  ipcMain.on('checkForUpdate', (event, url) => {
    win && win.webContents.send('upPackgeMsg', {
      status: 999,
      message: `执行自动更新检查……[${url}]`
    })
    //设置检查更新的链接
    autoUpdater.setFeedURL(url)
    setTimeout(()=>{
      autoUpdater.checkForUpdates()
    },0)
  })

  // 开始更新
  ipcMain.on('isUpdateNow', () => {
    win && win.webContents.send('upPackgeMsg', {
      status: 999,
      message: '开始更新……'
    })
    win.webContents.send('quit');
    autoUpdater.quitAndInstall(true, true) // 安装文件
    if(win && win.destroy){
      win.destroy()
    }
    app.quit()
  })

  // 打开外部链接
  ipcMain.on('openLink', (event, params) => {
    shell.openExternal(params)
  })
}


// 自动检测更新
function handleUpdate () {
  // 更新地址
  const message = {
    error: {
      status: -1,
      message: '检查更新出错'
    },
    success: {
      status: 1,
      message: '更新完成'
    }
  }

  // 设置是否自动下载,默认是true
  autoUpdater.autoDownload = true
  autoUpdater.autoInstallOnAppQuit = true // 如果安装包下载好了,那么当应用退出后是否自动安装更新
  if (process.env.NODE_ENV === 'development') {
    autoUpdater.updateConfigPath = path.join(
      __dirname,'/win-unpacked/resources/app-update.yml'
    )
  } else {
     autoUpdater.updateConfigPath = path.join(__dirname, '../app-update.yml')
  }
  // 更新失败
  autoUpdater.on('error', function () {
    //发送消息  接口:$electron.ipcRenderer.on("upPackgeMsg",(event,msg)=>{})
    win && win.webContents.send('upPackgeMsg', message.error)
  })

  // 开始执行检查更新
  autoUpdater.on('checking-for-update', function () {
    //发送消息
    win && win.webContents.send('upPackgeMsg', {
        status: 3,
        message: '开始检查版本……'
      })
  })
  // 检测到新版本
  autoUpdater.on('update-available', function (info) {
    let updaterCacheDirName = 'xxx_app-updater'
    // 有更新,删除本地安装包
    const updatePendingPath = path.join(
      autoUpdater.app.baseCachePath,
      updaterCacheDirName,
      'pending'
    )
    fs.emptyDir(updatePendingPath)
    //发送消息
    win && win.webContents.send('upPackgeMsg', {
        status: 4,
        message: '检测到新版本……'
      })
  })
  //没有更新的
  autoUpdater.on('update-not-available', function (info) {
  //发送消息
    win && win.webContents.send('upPackgeMsg', {
        status: 5,
        message: '当前以及是最新版本……'
      })
  })

  // 更新下载进度事件
  autoUpdater.on('download-progress', function (progressObj) {
   //发送消息
    win && win.webContents.send('upPackgeMsg', {
        status: 2,
        message: '下载文件中……',
        progress: progressObj.percent
      })
  })

  //更新下载成功
  autoUpdater.on('update-downloaded', function (
    event,
    releaseNotes,
    releaseName,
    releaseDate,
    updateUrl,
    quitAndUpdate
  ) {
     //发送消息
    win && win.webContents.send('upPackgeMsg', message.success)
  })
}

3) 挂载更新和ipc事件

/**
 * 主进程生命周期
 */
app.on('ready', async () => {
   //创建窗口
  createWindow()

  // 开机自启配置
  // app.setLoginItemSettings({
  //   openAtLogin: true,
  //   openAsHidden: true,
  //   path: process.execPath,
  //   args: ['--processStart', `"${exeName}"`]
  // })

  
  const gotTheLock = app.requestSingleInstanceLock()
  if (!gotTheLock) {
    app.quit()
  } else {
    app.on('second-instance', (event, commandLine, workingDirectory) => {
      // 当运行第二个实例时,将会聚焦到mainWindow这个窗口
      if (win) {
        if (win.isMinimized()) win.restore()
        win.focus()
        win.show()
      }
    })
  }
  

  // 注册ipc事件
  ipcEventInit()
  
  // 初始化Update配置
  handleUpdate()
  
})

 3.package.json 或者 vue.config.js (需要配置publish,否则就不生成latest.yml)

module.exports = {
  pluginOptions: {
    electronBuilder: {
      builderOptions: {
        //更新需要的配置
        publish: [
          {
            provider: 'generic',
            url: ''
          }
        ],
        appId: '',
        //其他配置
        win: {
          requestedExecutionLevel: 'highestAvailable',
          icon: './public/icon/favicon.ico',
          target: [
            {
              target: 'nsis',
              arch: [
                // 这个意思是打出来32 bit + 64 bit的包,但是要注意:这样打包出来的安装包体积比较大,所以建议直接打32的安装包。
                'x64'
              ]
            }
          ]
        },
        mac: {
          target: ['dmg', 'zip'],
          category: 'public.app-category.business',
          icon: './public/icon/favicon.png',
          entitlements: "entitlements.mac.plist",
          hardenedRuntime: true,
          extendInfo: {
            NSMicrophoneUsageDescription: "请允许本程序访问您的麦克风",
            NSCameraUsageDescription: "请允许本程序访问您的摄像头"
          }
        },
        linux: {
          icon: './public/icon',
        },
        nsis: {
          oneClick: false, // 一键安装
          perMachine: false, // 是否开启安装时权限限制(此电脑或当前用户)
          allowElevation: true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
          allowToChangeInstallationDirectory: true, // 允许修改安装目录
          installerIcon: './public/icon/favicon.ico', // 安装图标
          uninstallerIcon: './public/icon/favicon.ico', // 卸载图标
          installerHeaderIcon: './public/icon/favicon.ico', // 安装时头部图标
          createDesktopShortcut: true, // 创建桌面图标
          createStartMenuShortcut: true, // 创建开始菜单图标
          shortcutName: '', // 图标名称
          // artifactName:'${productName}${version}.${ext}'//不可如此
          // artifactName:'${productName}.${ext}'
          artifactName: '${productName} Setup ${version}.${ext}'
        },
        productName: ''//安装包名称
      },
      target: "electron-renderer"
    }
  }
}

4.autoUpdater实现exe更新的时候需要再服务器上部署个人站点,需要以下几个文件

---latest.yml  (高版本bulider的时候生成)

---xxx_1.0.0.exe.blockmap(当前版本bulider生成)

---xxx_1.3.0.exe(高版本bulider生成)

---xxx_1.3.0.exe.blockmap(高版本bulider生成)

你可能感兴趣的:(electron,js,前端,javascript,vue.js)