转载

Electron项目在windows系统下如何实现自动更新

困扰多日的electron在windows系统下自动更新的问题,终于得到解决,以下是填坑过程。

此教程仅适用于以下条件,使用条件外的,例如使用别的打包方式,未必适用此教程,慎重!

1、系统:windows 64位操作系统

2、使用electron-boilerplate-vue脚手架,其中electron为v1.2.1,vue为v1.0.25

3、使用electron-packager和grunt-electron-installer打包成安装文件

教程开始

(以打包成windows64位安装包并自动更新为例)

------------->第一步:

首先确保你的项目已安装electron-packager,因为我们要使用electron-packager进行第一步的打包,若未安装请安装,并在项目根目录的package.json的script下有类似这条的命令,命令里要有版本号,具体命令书写要求请阅读electron-packager的说明。

参见下图橘色标注的

Electron项目在windows系统下如何实现自动更新

满足以上要求后,在GitBash中执行 cnpm run-script packager64

Electron项目在windows系统下如何实现自动更新

执行完成后,会在项目根目录下生成一个文件夹OutApp(我在命令中要求的),文件夹里面的文件名称为Client-win32-x64(也是我在命令中要求的),双击文件Client.exe,如果可以正常运行,说明第一步的打包没有问题。

Electron项目在windows系统下如何实现自动更新

------------->第二步:

安装electron-squirrel-startup:

npm install electron-squirrel-startup

安装grunt-electron-installer:

npm install -g grunt-cli

npm install grunt grunt-electron-installer --save-dev

安装后,在项目根目录下建Gruntfile.js和gruntPackage.json,包含的代码分别为

Gruntfile.js:

var grunt=require('grunt');

//配置
grunt.config.init({
    pkg: grunt.file.readJSON('gruntPackage.json'),
    'create-windows-installer': {
        x64:{
            version:'1.0.0',
            authors:'JXB-XL',
            projectUrl:'',
            appDirectory:'./OutApp/Client-win32-x64',//要打包的输入目录
            outputDirectory:'./OutPut',//grunt打包后的输出目录
            exe:'Client.exe',
            description:'Client',
            setupIcon:"./app/assets/icon/jxb.ico",
            noMsi:true
        }
    }
});

//加载任务
grunt.loadNpmTasks('grunt-electron-installer');

//设置为默认
grunt.registerTask('default', ['create-windows-installer']);

配置内容详见grunt的官方文档

gruntPackage.json:

{
  "name": "Client",
  "version": "1.0.0",
  "devDependencies": {
    "grunt": "^1.2.0",
    "grunt-electron-installer": "^2.1.0"    
  }
}

------------->第三步:

在你的主进程的js中添加以下代码,并调用函数

const electron = require('electron')
//自动更新
const autoUpdater = electron.autoUpdater
function startupEventHandle(){
  if(require('electron-squirrel-startup')) return;
  var handleStartupEvent = function () {
    if (process.platform !== 'win32') {
      return false;
    }
    var squirrelCommand = process.argv[1];
    switch (squirrelCommand) {
      case '--squirrel-install':
      case '--squirrel-updated':
        install();
        return true;
      case '--squirrel-uninstall':
        uninstall();
        app.quit();
        return true;
      case '--squirrel-obsolete':
        app.quit();
        return true;
    }
      // 安装
    function install() {
      var cp = require('child_process');    
      var updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'update.exe');
      var target = path.basename(process.execPath);
      var child = cp.spawn(updateDotExe, ["--createShortcut", target], { detached: true });
      child.on('close', function(code) {
          app.quit();
      });
    }
    // 卸载
    function uninstall() {
      var cp = require('child_process');    
      var updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'update.exe');
      var target = path.basename(process.execPath);
      var child = cp.spawn(updateDotExe, ["--removeShortcut", target], { detached: true });
      child.on('close', function(code) {
          app.quit();
      });
    }
  };
  if (handleStartupEvent()) {
    return ;
  }
}
function updateHandle(){
  ipc.on('check-for-update', function(event, arg) {
    let appName='400电话系统';
    let appIcon=__dirname + '/assets/jxb.ico';
    let message={
      error:'检查更新出错',
      checking:'正在检查更新……',
      updateAva:'下载更新成功',
      updateNotAva:'现在使用的就是最新版本,不用更新',
      downloaded:'最新版本已下载,将在重启程序后更新'
    };
    const os = require('os');
    const {dialog} = require('electron');
    autoUpdater.setFeedURL('放最新版本文件的文件夹的服务器地址');
    autoUpdater.on('error', function(error){
      return dialog.showMessageBox(mainWindow, {
          type: 'info',
          icon: appIcon,
          buttons: ['OK'],
          title: appName,
          message: message.error,
          detail: '/r'+error
      });
    })
    .on('checking-for-update', function(e) {
        return dialog.showMessageBox(mainWindow, {
          type: 'info',
          icon: appIcon,
          buttons: ['OK'],
          title: appName,
          message: message.checking
      });
    })
    .on('update-available', function(e) {
        var downloadConfirmation = dialog.showMessageBox(mainWindow, {
            type: 'info',
            icon: appIcon,
            buttons: ['OK'],
            title: appName,
            message: message.updateAva
        });
        if (downloadConfirmation === 0) {
            return;
        }
    })
    .on('update-not-available', function(e) {
        return dialog.showMessageBox(mainWindow, {
            type: 'info',
            icon: appIcon,
            buttons: ['OK'],
            title: appName,
            message: message.updateNotAva
        });
    })
    .on('update-downloaded',  function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
        var index = dialog.showMessageBox(mainWindow, {
            type: 'info',
            icon: appIcon,
            buttons: ['现在重启','稍后重启'],
            title: appName,
            message: message.downloaded,
            detail: releaseName + "/n/n" + releaseNotes
        });
        if (index === 1) return;
        force_quit = true;
        autoUpdater.quitAndInstall();
    });
    autoUpdater.checkForUpdates();
 });
}

------------->第四步:

执行grunt,在你指定的目录生成三个文件,exe文件是安装包,RELEASES包含安装及版本信息,nupkg文件目前还没搞懂。

Electron项目在windows系统下如何实现自动更新

到目前为止,1.0.0版本的安装文件已经搞定,双击exe文件后,弹出绿色的安装动画,无法选择安装目录,会自动安装在C:UsersAdministratorAppDataLocal下,安装结束后动画消失,并自动创建了快捷方式

Electron项目在windows系统下如何实现自动更新

------------->第五步:

到目前为止,低版本的桌面应用已打包并安装完毕,我把版本号写在了页面上,可以看到是1.0.0版本的

Electron项目在windows系统下如何实现自动更新

那么怎么更新到新的版本呢?

方法如下:

1、修改版本信息,包括Gruntfile.js、gruntPackage.json、package.json下面所有的版本信息,改为1.0.1,然后从第一步开始执行,直到第四步,获得1.0.1版本的三个文件(release、exe、nupkg)后,将这三个文件上传到放最新版本文件的文件夹的服务器地址,对的,这个就是对应的主进程js中的autoUpdater.setFeedURL(第三步中)。

2、重启1.0.0桌面应用,点击检查更新(这里,我使用了ipc,即渲染进程向主进程发送消息,主进程监听'check-for-update',即第三步中的ipc.on('check-for-update', function(event, arg) {}))。

3、分别弹出以下窗口:

Electron项目在windows系统下如何实现自动更新

Electron项目在windows系统下如何实现自动更新

Electron项目在windows系统下如何实现自动更新

点击现在重启,就会自动关闭1.0.0版本的,并打开1.0.1版本的,打开后发现,已经更新成功

Electron项目在windows系统下如何实现自动更新

再点击检查更新,会弹出

Electron项目在windows系统下如何实现自动更新

再打开安装目录,会发现多了一个1.0.1的文件夹

Electron项目在windows系统下如何实现自动更新

你可以在自动更新成功后,用node将之前的1.0.0文件夹删除。

自动更新结束!

参考文章

从零开始使用Electron + jQuery开发桌面应用 (二) 打包应用 https://segmentfault.com/a/11...

【译】Electron 自动更新的完整教程(Windows 和 OSX) https://segmentfault.com/a/11...

1、开发阶段就进行检查更新,报错:Cannot find squirrel,这是因为此桌面应用没有安装,必须在安装后才能执行检查更新

2、桌面应用安装成功后,点击检查更新,报错:another instance is exist,这是因为首次安装后,不能进行检查更新,要想检查更新,必须重启应用,且重启间隔尽量在一分钟以上。自动更新后不会有这个问题,仅发生在首次安装后。

3、你的exe文件中不能包含数字,否则也会报错。

原文  https://segmentfault.com/a/1190000008287730
正文到此结束
Loading...