Electron自動更新詳解—包教會版

★ 本人在公司項目中實現的Electron更新功能。

★ 將實現更新過程的每一步都總結了出來,以及過程中我遇到了哪些問題,如何去解決的問題,有哪些注意事項。

★ 使用貼合實際應用的HTTP服務器做為載體實現更新,而非github。

開始:

程序配置:

  1. 構建工具:Electron-builder

  2. 更新工具:Electron-updater

在進行更新時,Electron 框架提供了更新的模塊。但是我的程序是使用Electron-builder進行的構建。我就使用了Electron-builder這個構建工具提供的自動更新的工具Electron-updater 來實現更新:在這里插入圖片描述

更新的思路流程:

  1. 首先安裝 electron-updater

    npm i electron-updater
    
  2. 進行更新的配置,官網有提供,在build下的 publish 中進行設置

    publish: {    provider: "generic", //generic通用HTTP服務器,當然有些人使用github做為更新載體這個地方的值就寫github,我使用的是http服務器,在局域網中使用。url: "http://xxxxxx/electron-updater" // 指向服務器對應更新的目錄,這個路徑的后綴electron-updater是我自定義的,具體原因文章最后講。channel: "latest",
    },
    
  3. 單獨新建了一個文件,來寫更新的邏輯代碼,重點來咯…

    (下列代碼意思都有詳細注釋)

    /*** 應用更新*/
    const { app, dialog, ipcMain, nativeImage } = require("electron");
    const { autoUpdater } = require("electron-updater");
    const log = require("electron-log"); // 為了輸出更新的日志:為安裝了 electron-log => npm i electron-log
    const path = require("path");function initAppUpdate(win) {// 配置日志,這個日志在 windows:C:\Users\Administrator\AppData\Roaming\你的程序名\logsautoUpdater.logger = log;autoUpdater.logger.transports.file.level = "info";// 禁用增量更新:代表用戶每次進行更新,都會將服務器上完整的程序進行下載更新,而不會更新指定修改的塊文件。// 當然肯定是增量更新更好,但是為什么我禁用了呢,文章最后講。autoUpdater.disableDifferentialDownload = true// 退出時自動安裝:當用戶使用程序的時候,按兵不動。等待用戶關閉程序了退出了之后,程序自動安裝,這樣下次用戶再次打開就是更新后的程序,但我為了讓客戶感知到更新,我禁用了退出時自動安裝。autoUpdater.autoInstallOnAppQuit = false;// 檢查更新(應用啟動時觸發)app.whenReady().then(() => {autoUpdater.checkForUpdates();});// 監聽下載完成事件(這里就是具體給用戶展示的更新的對話框,這個對話框的視圖在文章開頭我貼出來了)autoUpdater.on("update-downloaded", () => {dialog.showMessageBox(win, {type: "info",buttons: ["稍后", "立即安裝"],message: "更新已下載",detail: "新版本已就緒,是否立即安裝?",defaultId: 1, // 默認選中"立即安裝"(索引1)cancelId: 0, // 按Esc鍵等同于點擊"取消"}).then((res) => {if (res.response === 1) autoUpdater.quitAndInstall(); // 如果他對話框點擊“立即安裝”,就退出開始安裝});});// 錯誤處理autoUpdater.on("error", (err) => {log.error("更新失敗", err);});checkUpdate(win);
    }// 渲染進程觸發的檢查更新(這個我在程序里有個專門讓用戶用來檢測更新的地方)
    function checkUpdate(win) {ipcMain.handle("checkUpdate", async () => {const res = await autoUpdater.checkForUpdates();if (!res.isUpdateAvailable) {dialog.showMessageBox(win, {type: "info",buttons: ["我知道了"],message: "當前版本已經是最新版本",icon: loadIcon(),});}});
    }// 加載圖標(兼容開發和生產環境)
    function loadIcon() {try {let iconPath = path.join(__static, "right.png");return nativeImage.createFromPath(iconPath);} catch (e) {console.error("加載圖標失敗:", e);return null;}
    }// 這個函數,要引入到主進程的啟動程序文件里,還要將win傳參給該函數
    // 為什么要傳遞win呢? 因為你不傳的話,這個提示更新的dialog就和程序是兩個程序。如果你傳了win給dialog的話,dialog就在當前win上彈出。
    module.exports = { initAppUpdate };
    
  4. 將上面的 initAppUpdate 函數引入啟動程序文件,我這里的是background.js

在這里插入圖片描述

  1. 更新的配置到此已經都完成了。接下來要確定程序的版本號,在package.json 中有 version 這個鍵,設置一個程序版本號。比如你這次打包的程序是1.0.0,那么下次更新就是1.0.1。程序的更新是去檢測版本號是不是更新了,版本號更新了才會拉取更新的程序文件。(每次更新構建的時候,記得提高版本號)

  2. 打包構建:運行 npm run electron:build ,在構建后的目錄就會有 latest.yml 這個文件和 程序文件等。

  3. 構建成功后,你需要在服務器上建一個目錄,用來放程序文件等。

    1. 在你服務器新建一個目錄(我命名為 electron-updater),上傳文件:

      1. 第一個文件:latest.yml 這個文件包含了更新的版本信息以及程序包的信息等。

      2. 第二個文件:xxx.exe,應用程序。

      3. 第三個文件:xxx.exe.blockmap ,塊映射文件。用于增量更新,每次更新只更新變動的文件。

        但是有需要注意的事項:

        1. 你想要實現增量更新,需要將 .blockmap 塊映射文件上傳到對應的服務器目錄下,并且你還要保留更新前版本的塊映射文件。因為增量更新,需要比對更新前的塊映射文件和準備要更新的塊映射文件之間的差異,來實現增量更新。
        2. 比如:你服務器上的程序版本現在是1.0.0,現在程序要更新為1.0.1,那么你想讓客戶端實現增量更新,你的服務器需要放置的文件有
          1. 版本 1.0.1latest.yml 文件
          2. 版本 1.0.1xxx.exe 文件
          3. 版本 1.0.1xxx.exe.blockmap 文件
          4. 版本 1.0.0xxx.exe.blockmap 文件
        3. 還有一個增量更新的注意事項,寫在下面了👇
    2. 先把你在服務器上創建的放置更新文件、程序文件的目錄映射出去。也就是為了解決文章開始寫到的配置 publish 的時候,其中有個 url:http://xxxxxx/electron-updater,這個 url 就是直接訪問我們新建的這個目錄。

      1. 我新建的目錄名字叫做 electron-updater 目錄名稱。但是我在服務器上創建的 electron-updater 并不和 url 中的 electron-updater 是一個哦,是因為我用 electron-updater 這個路徑代理了 electron-updater 這個目錄,當然代理的路徑也可以改為別的,那么這時 url 的對應路徑也要改。

      2. 如何讓 http://xxxxxx/electron-updater 訪問到服務器上創建的 electron-updater 放置文件的目錄呢?使用代理服務器!

        當我開發測試的時候,我使用的是 nginx 來映射的目錄。測試了一下,發現實現了更新的功能、以及增量更新,一切都成功了。但是了解到使用方的服務器代理使用的 apache ,所以我又使用 apache 來實現,這次遇到問題了,在測試實現增量更新的時候,一直報錯響應頭的 Content-Type 錯誤,針對該錯誤我去 apache 添加響應頭,測試依舊有新報錯,隨后就沒有再去嘗試了。所以開頭寫到了,我采用了完整更新,而非增量更新。完整更新都是可以正常下載更新,只有使用 apache 的時候增量更新有問題。但使用 nginx 是不用格外配置就可以成功實現 完整更新 和 增量更新,所以沒有代理服務器要求的,使用 nginx 方便一些。

        1. nginx 配置

          在這里插入圖片描述

        2. apache 配置

          # 映射本地目錄到URL路徑
          Alias "/electron-updater" "D:/xxx/electron-updater"
          ...
          

總結:

  1. 注意我在配置更新的時候,禁用了退出程序后自動更新,當然也可以打開這個配置哦。用戶打開程序再次退出關閉后,自動更新程序,這個功能還是挺不錯的。
  2. 保存路徑:
    1. 程序更新日志保存路徑:
      C:\Users\Administrator\AppData\Roaming\你的程序名\logs
    2. 程序更新下載后的保存路徑:
      C:\Users\Administrator\AppData\Local\xxxxx_electron-updater\pending
  3. 一定要注意有新版本后,要提高程序的版本號,再 build 打包構建哦~
  4. 此外我還設置了一個小功能,就是不僅在程序剛打開的時候去檢測是否有更新。用戶在使用的過程中也加了按鈕可以讓用戶點擊查看是否需要更新,如果不需要更新,會提示用戶此版本為最新版本,多么貼心的功能… (前面的代碼里面有寫到)

此時Electron的更新功能,或者說Electron的自動更新就算圓滿結束!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/85477.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/85477.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/85477.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Apache RocketMQ 消息過濾的實現原理與騰訊云的使用實踐

導語 本文將系統闡述 Apache RocketMQ 消息過濾機制的技術架構與實踐要點。首先從業務應用場景切入,解析消息過濾的核心價值;接著介紹 Apache RocketMQ 支持的兩種消息過濾實現方式,幫助讀者建立基礎認知框架;隨后深入剖析 SQL 語…

安卓JetPack篇——LifeCycle原理

LifeCycle 一、什么是Lifecycle 具備宿主生命周期感知能力的組件。它能持有組件(如Activity或Fragment)生命周期狀態的信息,并且允許其他觀察者監聽宿主的狀態。 二、基本原理 1、安卓10以下版本 隱形的Fragment注入在LifecycleOwner&am…

CSS 圓角邊框屬性(`border-radius`)筆記

一、作用: 用于設置元素四個角的圓角效果,讓元素不再死板,更加柔和。 二、基本語法: border-radius: 圓角大小; 單位:px(像素)或 %(百分比) 示例: div { ?…

python自助棋牌室管理系統

目錄 技術棧介紹具體實現截圖系統設計研究方法:設計步驟設計流程核心代碼部分展示研究方法詳細視頻演示試驗方案論文大綱源碼獲取/詳細視頻演示 技術棧介紹 Django-SpringBoot-php-Node.js-flask 本課題的研究方法和研究步驟基本合理,難度適中&#xf…

計算機——硬盤分區和格式化

硬盤驅動器 硬盤驅動器(HDD)是一種成熟、經濟的大容量存儲解決方案。它的核心優勢在于每GB成本低和超大容量。然而,其機械結構帶來的速度瓶頸、噪音、功耗和對物理沖擊的敏感性是其主要的缺點。隨著 SSD 價格的持續下降和性能的絕對領先&…

從IEC到UL:技術主權競爭下的斷路器合規性戰略

1 國際標準體系割裂的現狀 在全球低壓電器領域,國際標準體系呈現出日益明顯的割裂態勢。當前主要存在四大標準體系:國際通用的??IEC標準體系??、歐洲采用的??EN標準體系??、北美實施的??UL與CSA標準體系??,以及具有地域特色的?…

第十六屆藍橋杯_省賽B組(D).產值調整

題目如下 這道題看似很簡單,其實還是得觀察一下,要不然就會… 話不多說回到題目,這個題的坑就在于當A,B,C三個產值相同的時候,再怎么變還是之前的產值,或者也可以通過另外一種方法理解: 通過一個案例來舉…

設計模式 | 單例模式——餓漢模式 懶漢模式

單例模式 文章目錄 單例模式一、餓漢模式(Eager Initialization)1. 定義2. 特點3. 餓漢單例模式(定義時-類外初始化)4. 實現細節 二、懶漢模式(Lazy Initialization)1. 定義2. 特點3. 懶漢單例模式&#xf…

dify本地部署及添加ollama模型(ubuntu24.04)

說明:ubuntu是虛擬機的,用的橋接模式,與本地同局域網不同ip地址。 參考VM虛擬機網絡配置(ubuntu24橋接模式):配置靜態IP前提:需要有docker及docker-compose環境 參考ubuntu24安裝docker及docker…

Python爬蟲實戰:研究multiprocessing相關技術

一、引言 1.1 研究背景與意義 隨著互聯網信息的爆炸式增長,網絡爬蟲已成為獲取海量數據的重要工具。傳統的單線程爬蟲在面對大規模數據采集任務時效率低下,無法充分利用現代計算機多核 CPU 的優勢。多線程爬蟲雖然在一定程度上提高了效率,但受限于 Python 的全局解釋器鎖(…

6.18 redis面試題 日志 緩存淘汰過期刪除 集群

Redis有哪2種持久化方式?分別的優缺點是什么? Redis 的重寫 AOF 過程是由后臺子進程 bgrewriteaof 來完成的。 過期刪除策略和內存淘汰策略有什么區別? 內存淘汰策略是在內存滿了的時候,redis 會觸發內存淘汰策略,來淘…

什么時候會發生內存泄漏?

1. 內存泄漏是什么? 定義:內存泄漏是指程序中的對象已經不再需要,但由于被其他對象錯誤引用,導致垃圾回收器(GC)無法回收它,從而長期占用內存空間的現象。 2. 內存泄漏的危害 問題具體表現內存…

用RSA算法模擬類的適配器模式

“RAS算法”這個術語本身并不常見或標準,它可能指向兩個主要領域的不同概念,具體取決于上下文: 更可能是拼寫錯誤:指 RSA 算法(密碼學) 這是最常見的情況。 “RAS” 極有可能是 “RSA” 的拼寫錯誤。RSA 算…

CARSIM-與C#自動化測試方案

using System; using System.Runtime.InteropServices; using System.Collections.Generic;namespace CarSimAutomation {/// <summary>/// CarSim COM 自動化測試接口/// 封裝所有 CarSim COM 功能用于自動化測試/// </summary>[ComVisible(true)][ClassInterface…

企微CRM系統中的任務分配與效率提升技巧

在數字化管理時代&#xff0c;企業微信(企微)與CRM系統的深度融合&#xff0c;為企業提供了更高效的客戶管理與團隊協作方案。企微CRM軟件不僅整合了客戶溝通、銷售跟進、數據分析等功能&#xff0c;還能通過智能任務分配優化團隊效率。本文將深入探討企微CRM管理系統的任務分配…

day66—BFS—最短的橋(LeetCode-934)

題目描述 給你一個大小為 n x n 的二元矩陣 grid &#xff0c;其中 1 表示陸地&#xff0c;0 表示水域。 島 是由四面相連的 1 形成的一個最大組&#xff0c;即不會與非組內的任何其他 1 相連。grid 中 恰好存在兩座島 。 你可以將任意數量的 0 變為 1 &#xff0c;以使兩座…

FramePack 安裝指南(中文)

FramePack 安裝指南&#xff08;中文&#xff09; -Windows FramePack 是最前沿的 AI 視頻生成框架&#xff0c;以極小的硬件需求顛覆視頻創作&#xff01;它能在僅 6GB 筆記本 GPU 內存上&#xff0c;驅動 13B 模型以 30 FPS 生成超長 120 秒視頻&#xff0c;幾乎無內容限制&…

Redis Sentinel 非集群模式高可用部署指南

1. Sentinel 在非集群模式的定位 一句話&#xff1a;在單主多從架構中&#xff0c;用 Sentinel 替你盯哨——探測故障、選舉新主、通知客戶端。 核心四職能&#xff1a; 職能作用點Monitoring定時 PING 主從&#xff0c;自身也互相探測Notification通過日志/PubSub/外部調用報…

2025Java面試八股文

文章目錄 Java基礎JVM多線程SpringSpring Boot數據庫與SQL分布式系統其他 Java基礎 自動裝箱與拆箱&#xff1a;Java中基礎數據類型與包裝類之間的轉換。例如&#xff0c;Integer x 1; 是裝箱&#xff0c;int y x; 是拆箱。Object類常用方法&#xff1a;如clone()、getClass…

寶塔安裝nginx-rtmp,音視頻直播

前置&#xff1a;需要自己開發音視頻直播&#xff0c; 注意不是實時音視頻&#xff0c;不是一對一視頻聊天&#xff0c;不是視頻會議 方案有 srs &#xff0c;nginx-rtmp&#xff0c;live555&#xff0c;node-media-server&#xff0c;EasyDarwin等 今天是說 nginx-rtmp 怎么…