自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Electron 自動(dòng)更新,繞過(guò) latest.yml 使用自定義接口

開(kāi)發(fā) 前端
在開(kāi)發(fā)階段想測(cè)試一下檢測(cè)更新的流程走沒(méi)走通,可能不太好測(cè)試,因?yàn)?Electron 默認(rèn)在開(kāi)發(fā)環(huán)境下會(huì)繞過(guò)更新檢測(cè)。開(kāi)發(fā)環(huán)境下 Electron 啟動(dòng)后,如果接入了自動(dòng)更新。

大家好,我是楊成功。

在上一篇文章《手?jǐn)] Electron 自動(dòng)更新,再繁瑣也要搞懂它》中,我們?cè)敿?xì)介紹了 Electron 自動(dòng)更新的全流程。

簡(jiǎn)單來(lái)說(shuō),就是打包生成 latest.yml 文件和安裝包,并上傳到服務(wù)器??蛻?hù)端打開(kāi)時(shí)訪(fǎng)問(wèn)服務(wù)端的 latest.yml 地址,判斷是否有新版本,有則自動(dòng)下載新包并更新。

對(duì)于以上的更新流程,很多朋友在評(píng)論區(qū)留言表示不夠靈活,比如:

  • 只能自動(dòng)更新嗎?能不能通過(guò)后端接口來(lái)判斷是否更新?
  • 必須要用 latest.yml 嗎?能不能繞開(kāi)它?
  • 如何區(qū)分 Window、Mac、Mac M1 三種安裝包?

下面我們一一解答這些問(wèn)題,并手?jǐn)]一個(gè)更靈活的自動(dòng)更新接口。

如何本地測(cè)試更新?

在開(kāi)發(fā)階段想測(cè)試一下檢測(cè)更新的流程走沒(méi)走通,可能不太好測(cè)試,因?yàn)?Electron 默認(rèn)在開(kāi)發(fā)環(huán)境下會(huì)繞過(guò)更新檢測(cè)。

開(kāi)發(fā)環(huán)境下 Electron 啟動(dòng)后,如果接入了自動(dòng)更新,主進(jìn)程控制臺(tái)會(huì)打印下面的信息:

Skip checkForUpdates because application is not packed and dev update config is not forced

意思是當(dāng)前是開(kāi)發(fā)環(huán)境,未打包,所以繞過(guò)檢測(cè)。Electron 通過(guò) app.isPackaged 的值來(lái)判斷是否打包,那么在開(kāi)發(fā)環(huán)境下,我們可以修改一下這個(gè)值:

import { app } from 'electron';

// 未打包時(shí)是開(kāi)發(fā)環(huán)境
if (!app.isPackaged) {
  Object.defineProperty(app, 'isPackaged', {
    get: () => true,
  });
}

重新運(yùn)行,大概率會(huì)看到第二個(gè)錯(cuò)誤:

Error: ENOENT: no such file or directory /xxxx/app-update.yml

因?yàn)闆](méi)有打包嘛,所以找不到 app-update.yml 這個(gè)文件,索性我們就創(chuàng)建一個(gè)。

在根目錄下創(chuàng)建一個(gè) dev-update.yml 文件(文件名可自定義),寫(xiě)入配置:

provider: generic
updaterCacheDirName: demo-updater # 下載目錄

然后在開(kāi)發(fā)環(huán)境指定這個(gè)配置文件地址:

import { app } from 'electron';
import path from "path";

if(!app.isPackaged) {
  ...
  autoUpdater.updateConfigPath = path.join(__dirname, "../../dev-update.yml");
}

重新運(yùn)行項(xiàng)目,會(huì)發(fā)現(xiàn)檢測(cè)更新的邏輯可以正常執(zhí)行了。

能不能繞開(kāi) latest.yml,走后端接口?

可能大家希望的檢查更新流程是這樣:

調(diào)用后端的 API 接口,接口返回 JSON 格式數(shù)據(jù),包含最新的版本號(hào)和安裝包下載地址。將該版本號(hào)與本地版本號(hào)做對(duì)比,如果不一樣則表示有更新,并執(zhí)行下載。

然而 electron-updater 是通過(guò) latest.yml 文件來(lái)獲取版本號(hào)等信息。latest.yml 是一個(gè)配置文件,內(nèi)容如下:

version: 1.0.2
files:
  - url: elapp_1.0.2.exe
    sha512: xxxxxx
    size: 72716511
path: elapp_1.0.2.exe
sha512: xxxxxx
releaseDate: '2023-11-29T02:28:28.032Z'

大家想繞過(guò)它,可能是因?yàn)?YAML 文件的內(nèi)容看不太懂,或者與接口格式不匹配。其實(shí)它就是一個(gè)普通的配置文件,轉(zhuǎn)換成 JSON 格式如下:

{
  "version": "1.0.2",
  "files": [
    {
      "url": "elapp_1.0.2.exe",
      "sha512": "xxxxxx",
      "size": "72716511"
    }
  ],
  "path": "elapp_1.0.2.exe"
}

可能有人會(huì)問(wèn):配置文件可以改成latest.json嗎,這樣后端就可以動(dòng)態(tài)返回了。

我仔細(xì)查閱過(guò)文檔,目前只支持 YAML 文件,不支持 JSON,所以 latest.yml 無(wú)法繞開(kāi)。但這只是官方說(shuō)法,咱還是有辦法滴。

經(jīng)過(guò)大量測(cè)試,我發(fā)現(xiàn)把 latest.yml 文件的內(nèi)容手動(dòng)改成 JSON 格式也是可以的。這樣的話(huà),就可以寫(xiě)一個(gè)接口來(lái)模擬 latest.yml 的地址。

假設(shè) latest.yml 的訪(fǎng)問(wèn)路由是/ele-app/latest.yml,那么寫(xiě)一個(gè)接口如下:

const app = require('express')()

app.get('/ele-app/latest.yml', (req, res, next) => {
  let resinfo = {
    version: "1.0.25",
    path: "xxx_1.0.25.exe"
    sha512: "xxxxxx"
  }
  res.send(resinfo)
})

該接口就是自定義的檢測(cè)更新接口。接口返回值中至少要包含version、path、sha512三個(gè)屬性(與 latest.yml 中的配置保持一致)。這樣我們不需要上傳 latest.yml 文件了,用該接口替代即可。

基于該檢測(cè)更新接口,接下來(lái)我們逐步實(shí)現(xiàn)自定義更新流程。

如何區(qū)分 Windows 和 Mac 系統(tǒng)

對(duì)于 Windows 和 Mac 兩個(gè)系統(tǒng)的更新,electron-updater 使用不同的配置文件,分別是 latest.yml  latest-mac.yml。

從上一步的檢測(cè)更新接口來(lái)看,不同的配置文件就是不同的路由,我們改造接口如下:

app.get('/ele-app/:platform', (req, res, next) => {
  let { platform } = req.params
  let resinfo = null
  // 返回 Windows 配置
  if(platform == 'latest.yml') {
    resinfo = {
      version: "1.0.2",
      path: "xxx_1.0.2.exe"
      sha512: "xxxxxx"
    }
  }
  // 返回 Mac 配置
  if(platform == 'latest-mac.yml') {
    resinfo = {
      version: "1.0.3",
      path: "xxx_1.0.3.dmg"
      sha512: "xxxxxx"
    }
  }
  if(!resinfo) {
    resinfo = { code: 400, msg: '參數(shù)錯(cuò)誤' }
  }
  res.send(resinfo)
})

上面代碼中,使用動(dòng)態(tài)路由返回 Windows 和 Mac 的配置,同時(shí)兼容了兩個(gè)平臺(tái)的更新檢測(cè)。

完整的自定義更新流程

經(jīng)過(guò)上面的介紹,自定義檢測(cè)更新的關(guān)鍵思路已經(jīng)講清楚了。完整的更新流程如下:

(1)打包各個(gè)平臺(tái)的安裝包,上傳服務(wù)器。

如何打包在上一篇介紹過(guò),就不展開(kāi)說(shuō)了。注意的是:現(xiàn)在你只需要上傳安裝包,不需要上傳 latest.yml 文件。

(2)在主進(jìn)程中設(shè)置更新地址,并手動(dòng)控制更新。

假設(shè)我們編寫(xiě)的檢測(cè)更新接口已經(jīng)部署,設(shè)置方法如下:

import { autoUpdater } from 'electron-updater';

// 設(shè)置檢測(cè)更新的地址
autoUpdater.setFeedURL('http://[xxx]/ele-app');
// 不自動(dòng)下載
autoUpdater.autoDownload = false;
// 觸發(fā)檢測(cè)
autoUpdater.checkForUpdatesAndNotify().catch();

// 監(jiān)聽(tīng)到可更新
autoUpdater.on('update-available', (info) => {
  // info 是檢測(cè)更新接口返回的數(shù)據(jù)
  if (info.can_download) {
    // can_download 是自定義屬性
    autoUpdater.downloadUpdate();
  }
});

(3)編寫(xiě)檢測(cè)更新接口,返回配置。

返回的配置我們可以自定義,假設(shè)返回結(jié)果如下:

{
  "version": "1.0.2",
  "path": "http://xxx/xxx_1.0.2.exe",
  "sha512": "xxxxxx",
  "can_download": false
}

上述示例中,接口返回了自定義屬性 can_download,我們?cè)诘冢?)步中使用了該屬性,用于判斷是否執(zhí)行下載更新。

通過(guò)這種方式,即便我們更新了安裝包,也可以自由決定是否要下載安裝。

這里有一個(gè)小驚喜:path 屬性的值可以是一個(gè)完整的安裝包地址,這樣可以把安裝包上傳到任意地方。如果值是一個(gè)文件名,那么會(huì)以第(2)步中 setFeedURL() 方法設(shè)置的地址為前綴。

提醒:sha512 屬性的值必須從打包生成的 latest.yml 中獲取,不可以隨意寫(xiě),否則在安裝時(shí)不能通過(guò)檢驗(yàn),會(huì)報(bào)這個(gè)錯(cuò):

Error: sha512 checksum mismatch

特別篇:Mac 如何區(qū)分 Intel 和 M1?

Mac 系統(tǒng)有兩種軟件包,分別對(duì)應(yīng) M1 芯片和 Intel 芯片,兩者不兼容。一般打包時(shí)我們也會(huì)構(gòu)建兩種安裝包。

那么在檢測(cè)更新時(shí),我們就需要返回適配當(dāng)前系統(tǒng)的安裝包。但不管是 M1 還是 Intel 都使用 latest-mac.yml 這一個(gè)配置文件,該如何區(qū)分呢?

這個(gè)時(shí)候就要從主進(jìn)程中獲取參數(shù),然后傳給接口了。步驟如下:

(1)在主進(jìn)程中,獲取系統(tǒng)架構(gòu),并通過(guò)請(qǐng)求頭傳給檢測(cè)更新接口。

import { autoUpdater } from 'electron-updater';

// 添加請(qǐng)求頭
autoUpdater.requestHeaders = {
  elearch: process.arch,
};

(2)在接口中接收參數(shù),并在返回 Mac 配置中判斷:

app.get('/ele-app/:platform', (req, res, next) => {
  let { platform } = req.params
  let { elearch } = req.headers

  if(platform == 'latest-mac.yml') {
    if(elearch == 'arm64') {
      // M1
      return {...}
    } else {
      // Intel
      return {...}
    }
  }
})

有了上面的邏輯,我們?cè)诖虬鼤r(shí)就可以單獨(dú)打兩個(gè)包,分別上傳,然后在檢測(cè)時(shí)返回不同的下載地址。

總結(jié)

本文使用自定義接口的方式,繞過(guò)了 latest.yml 配置文件,使自動(dòng)更新的靈活性更高,也更符合我們的常規(guī)習(xí)慣,但是需要維護(hù)一個(gè)更新接口。

如果不想維護(hù)接口,那么上傳 latest.yml 文件的方式更適合你。

責(zé)任編輯:姜華 來(lái)源: 程序員成功
相關(guān)推薦

2023-11-22 17:00:10

ElectronWeb

2015-02-12 15:33:43

微信SDK

2015-02-12 15:38:26

微信SDK

2015-03-30 14:15:55

自動(dòng)更新Android

2021-11-08 22:24:04

Windows 10Windows微軟

2017-10-20 12:13:11

數(shù)據(jù)庫(kù)PostgreSQL時(shí)間戳

2019-12-25 11:47:27

LinuxFVWM

2022-01-14 09:17:13

PythonAPISIX插件

2010-10-25 16:05:07

oracle自定義函數(shù)

2009-06-23 11:35:44

JSF的Naviati

2018-03-19 11:50:00

LinuxCentOS yum命令行

2010-05-24 11:27:20

SVN配置自動(dòng)更新WE

2021-05-28 08:58:41

Golang網(wǎng)卡metrics

2010-01-08 13:20:52

ibmdwWeb

2025-02-10 00:14:00

2022-09-13 15:44:52

VSLook插件

2021-10-28 08:39:22

Node Export自定義 監(jiān)控

2010-07-01 09:38:31

jQuery

2022-11-01 11:15:56

接口策略模式

2009-08-21 15:38:45

ControllerF
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)