Electron應用使用electron-builder配合electron-updater實現自動更新

開發客戶端必定要作的就是自動更新模塊,不然每次版本升級都是一個頭疼的事。
下面是Electron應用使用electron-builder配合electron-updater實現自動更新的解決方案。linux

1.安裝 electron-updater 包模塊web

npm install electron-updater --save

2.配置package.json文件
2.1 爲了打包時生成latest.yml文件,須要在 build 參數中添加 publish 配置。npm

"build": {
    "productName": "***",//隱藏軟件名稱
    "appId": "**",//隱藏appid
    "directories": {
      "output": "build"
    },
    "publish": [
      {
        "provider": "generic",
        "url": "http://**.**.**.**:3002/download/",//更新服務器地址,可爲空
      }
    ],
    "files": [
      "dist/electron/**/*"
    ],
    "dmg": {
      "contents": [
        {
          "x": 410,
          "y": 150,
          "type": "link",
          "path": "/Applications"
        },
        {
          "x": 130,
          "y": 150,
          "type": "file"
        }
      ]
    },
    "mac": {
      "icon": "build/icons/icon.icns",
      "artifactName": "${productName}_setup_${version}.${ext}"
    },
    "win": {
      "icon": "build/icons/icon.ico",
      "artifactName": "${productName}_setup_${version}.${ext}"
    },
    "linux": {
      "icon": "build/icons",
      "artifactName": "${productName}_setup_${version}.${ext}"
    }
  }

注意:配置了publish纔會生成latest.yml文件,用於自動更新的配置信息;latest.yml文件是打包過程生成的文件,爲避免自動更新出錯,打包後禁止對latest.yml文件作任何修改。若是文件有誤,必須從新打包獲取新的latest.yml文件!!!json

2.2 增長nsis配置(可省略)
nsis配置不會影響自動更新功能,可是能夠優化用戶體驗,好比是否容許用戶自定義安裝位置、是否添加桌面快捷方式、安裝完成是否當即啓動、配置安裝圖標等。nsis 配置也是添加在 build 參數中。 詳細參數配置可參見官方文檔 nsis配置segmentfault

"nsis": {
      "oneClick": true,
      "perMachine": true,
      "allowElevation": true,
      "allowToChangeInstallationDirectory": true,
      "createDesktopShortcut": true,
      "runAfterFinish": true,
      "installerIcon": "./build/icon.ico",
      "uninstallerIcon": "./build/icon.ico"
    },

3.配置主進程main.js文件(或主進程main中的index.js文件),引入 electron-updater 文件,添加自動更新檢測和事件監聽:
注意:必定要是主進程main.js文件(或主進程main中的index.js文件),不然會報錯。
注意:這個autoUpdater不是electron中的autoUpdater,是electron-updater的autoUpdater,不然坑你沒商量!windows

import { app, BrowserWindow, ipcMain } from 'electron'

// 注意這個autoUpdater不是electron中的autoUpdater
import { autoUpdater } from "electron-updater"
// 更新服務器地址,好比"http://**.**.**.**:3002/download/"
import {uploadUrl} from "../renderer/config/config";

// 檢測更新,在你想要檢查更新的時候執行,renderer事件觸發後的操做自行編寫
function updateHandle() {
  let message = {
    error: '檢查更新出錯',
    checking: '正在檢查更新……',
    updateAva: '檢測到新版本,正在下載……',
    updateNotAva: '如今使用的就是最新版本,不用更新',
  };
  const os = require('os');

  autoUpdater.setFeedURL(uploadUrl);
  autoUpdater.on('error', function (error) {
    sendUpdateMessage(message.error)
  });
  autoUpdater.on('checking-for-update', function () {
    sendUpdateMessage(message.checking)
  });
  autoUpdater.on('update-available', function (info) {
    sendUpdateMessage(message.updateAva)
  });
  autoUpdater.on('update-not-available', function (info) {
    sendUpdateMessage(message.updateNotAva)
  });

  // 更新下載進度事件
  autoUpdater.on('download-progress', function (progressObj) {
    mainWindow.webContents.send('downloadProgress', progressObj)
  })
  autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {

    ipcMain.on('isUpdateNow', (e, arg) => {
      console.log(arguments);
      console.log("開始更新");
      //some code here to handle event
      autoUpdater.quitAndInstall();
    });

    mainWindow.webContents.send('isUpdateNow')
  });

  ipcMain.on("checkForUpdate",()=>{
      //執行自動更新檢查
      autoUpdater.checkForUpdates();
  })
}

// 經過main進程發送事件給renderer進程,提示更新信息
function sendUpdateMessage(text) {
  mainWindow.webContents.send('message', text)
}

注:在添加自動更新檢測和事件監聽以後,在主進程createWindow中須要調用一下updateHandle()。以下圖所示:
圖片描述服務器

4.在視圖(View)層中觸發自動更新,並添加自動更新事件的監聽。
觸發自動更新:app

ipcRenderer.send("checkForUpdate");

監聽自動更新事件:electron

import { ipcRenderer } from "electron";
  ipcRenderer.on("message", (event, text) => {
            console.log(arguments);
            this.tips = text;
        });
        //注意:「downloadProgress」事件可能存在沒法觸發的問題,只須要限制一下下載網速就行了
        ipcRenderer.on("downloadProgress", (event, progressObj)=> {
            console.log(progressObj);
            this.downloadPercent = progressObj.percent || 0;
        });
        ipcRenderer.on("isUpdateNow", () => {
            ipcRenderer.send("isUpdateNow");
        });

注意:子進程中「downloadProgress」事件可能出現沒法觸發的問題,那是由於下載速度很快,就會跳過「downloadProgress」事件;只須要限制一下本地下載網速就行了!ide

爲避免屢次切換頁面形成監聽的濫用,切換頁面前必須移除監聽事件:

//組件銷燬前移除全部事件監聽channel
        ipcRenderer.removeAll(["message", "downloadProgress", "isUpdateNow"]);//remove只能移除單個事件,單獨封裝removeAll移除全部事件

5.項目打包
執行electron-builder進行打包,windows下會生成安裝包exe和latest.yml等文件,執行exe安裝軟件;Mac下會生成安裝包dmg、zip和latest-mac.yml文件,執行dmg安裝軟件。
注意:mac上不簽名也能夠打包成功,可是涉及到自動更新等須要身份認證的功能則不能用,也不能發佈到mac app store中。因此說通過代碼簽名的MAC包纔是完整的包。咱們這裏必定是通過代碼簽名的完整包!切記!
具體打包流程請參考:Electron 桌面應用打包(npm run build)簡述(windows + mac)
MAC打包中報Error: Could not get code signature for running application錯誤可參考:Electron 打包Mac安裝包代碼簽名問題解決方案
windows打包生成文件:
TIM%E6%88%AA%E5%9B%BE20180117165614.png

Mac打包生成文件:
TIM%E6%88%AA%E5%9B%BE20180117165401.png

6.軟件升級版本,修改package.json中的version屬性,例如:改成 version: 「1.1.0」 (以前爲1.0.0);
7.再次執行electron-builder打包,Windows下將新版本latest.yml文件和exe文件(MAC下將latest-mac.yml,zip和dmg文件)放到package.json中build -> publish中的url對應的地址下;
8.在應用中觸發更新檢查,electron-updater自動會經過對應url下的yml文件檢查更新;

windows上自動更新示例:

clipboard.png

clipboard.png

mac上自動更新示例:
clipboard.png

clipboard.png

附:項目目錄層次:
圖片描述

若是這篇文章對你的工做或者學習有幫助的話,請收藏或點個贊。若是對其中有什麼不明白的或者報錯,能夠留言或者加QQ羣140455228交流

注意:請支持原創,本文謝絕轉載,確有須要可連接到本文。本文連接地址:https://segmentfault.com/a/11...

相關文章
相關標籤/搜索