【Electron】—— 教程:在windows系統下實現自動更新

困擾多日的electron在windows系統下自動更新的問題,終於獲得解決,如下是填坑過程。
此教程僅適用於如下條件,使用條件外的,例如使用別的打包方式,未必適用此教程,慎重!vue


一、系統:windows7 64位操做系統
二、使用electron-boilerplate-vue腳手架,其中electron爲v1.2.1,vue爲v1.0.25
三、使用electron-packager和grunt-electron-installer打包成安裝文件,以及 Squirrel.Windows
四、請先安裝vs2015,並配置系統變量,保證Squirrel.Windows的安裝環境node


教程開始

注:此文不適合electron新手,須要對electron有必定的瞭解,需清楚electron主進程、渲染進程之間的關係,需清楚electron怎麼打包。git

(以打包成windows64位安裝包並自動更新爲例)github

------------->第一步:
首先確保你的項目已安裝electron-packager,由於咱們要使用electron-packager進行第一步的打包,若未安裝請安裝,並在項目根目錄的package.json的script下有相似這條的命令,命令裏要有版本號,具體命令書寫要求請閱讀electron-packager的說明。
參見下圖橘色標註的
圖片描述mongodb

注意 package.json 的額外字段 —— productName、author 和 description,雖然這幾個字段並非打包必備的,但它們會在Squirrel.Windows中使用到。
知足以上要求後,在GitBash中執行 cnpm run-script packager64npm

圖片描述

執行完成後,會在項目根目錄下生成一個文件夾OutApp(我在命令中要求的),文件夾裏面的文件名稱爲Client-win32-x64(也是我在命令中要求的),雙擊文件Client.exe,若是能夠正常運行,說明第一步的打包沒有問題。json

圖片描述

------------->第二步:
安裝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:segmentfault

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的官方文檔windows

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;
        autoUpdater.quitAndInstall();
    });
    autoUpdater.checkForUpdates();
 });
}

------------->第四步:
執行grunt,在你指定的目錄生成三個文件,exe文件是安裝包,RELEASES包含安裝及版本信息,nupkg文件目前還沒搞懂。
圖片描述

到目前爲止,1.0.0版本的安裝文件已經搞定,雙擊exe文件後,彈出綠色的安裝動畫,沒法選擇安裝目錄,會自動安裝在C:\Users\Administrator\AppData\Local下,安裝結束後動畫消失,並自動建立了快捷方式
圖片描述

------------->第五步:
到目前爲止,低版本的桌面應用已打包並安裝完畢,我把版本號寫在了頁面上,能夠看到是1.0.0版本的
圖片描述

那麼怎麼更新到新的版本呢?
方法以下:
一、修改版本信息,包括Gruntfile.js、gruntPackage.json、package.json下面全部的版本信息,改成1.0.1,而後從第一步開始執行,直到第四步,得到1.0.1版本的三個文件(release、exe、nupkg)後,將這三個文件上傳到放最新版本文件的文件夾的服務器地址,對的,這個就是對應的主進程js中的autoUpdater.setFeedURL(第三步中)。
二、重啓1.0.0桌面應用,點擊檢查更新(這裏,我使用了ipc,即渲染進程向主進程發送消息,主進程監聽'check-for-update',即第三步中的ipc.on('check-for-update', function(event, arg) {}))。
三、分別彈出如下窗口:
圖片描述

圖片描述

圖片描述

點擊如今重啓,就會自動關閉1.0.0版本的,並打開1.0.1版本的,打開後發現,已經更新成功

圖片描述

再點擊檢查更新,會彈出

圖片描述

再打開安裝目錄,會發現多了一個1.0.1的文件夾
圖片描述

你能夠在自動更新成功後,用node將以前的1.0.0文件夾刪除。
自動更新結束!

原理

引用自https://github.com/Squirrel/S...
一、根據設置的setFeedURL路徑,UpdateManager檢查路徑下的RELEASES文件,與安裝目錄下的RELEASES文件進行比對。
二、若是出現版本不一樣的狀況,將下載路徑中的更新包,下載完成後自動進行更新(包括修改快捷方式和清除舊版本)。
三、更新成功後,會保留上一個版本,並清除上一個版本以前的全部版本。

參考文章

從零開始使用Electron + jQuery開發桌面應用 (二) 打包應用https://segmentfault.com/a/11...
【譯】Electron 自動更新的完整教程(Windows 和 OSX)https://segmentfault.com/a/11...

一、開發階段就進行檢查更新,報錯:Cannot find squirrel,這是由於此桌面應用沒有安裝,必須在安裝後才能執行檢查更新

二、桌面應用安裝成功後,點擊檢查更新,報錯:another instance is exist,這是由於首次安裝後,一些安裝文件尚未退出,因此儘可能在安裝完畢的一分鐘後再檢查更新。自動更新後不會有這個問題,僅發生在首次安裝後。

三、你的exe文件名不能包含數字,不然也會報錯。

四、一些同窗說,安裝後檢查更新報錯:Cannot find module ‘electron-squirrel-startup’,應該是沒有安裝Squirrel.Windows的緣由,請先安裝Squirrel.Windows,須要vs2015的環境(vs2015須要下載並安裝,安裝會佔用C盤幾個G的空間,請先保證C盤有足夠空間。安裝後請設置系統變量,即在Path下添加C:\Program Files (x86)\MSBuild\14.0\Bin)

五、更換了辦公的電腦,系統變成win10,從新下載安裝環境後發現,若是現有的項目版本高於服務器上的項目版本,就會自動更新失敗,C盤的安裝目錄下的squirrel文件顯示'local version is greater than remote version'

相關文章
相關標籤/搜索