<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          研究Electron自動更新 系列一【近8k字】

          共 9189字,需瀏覽 19分鐘

           ·

          2021-01-18 22:33

          摘要

          閱讀本文需要 ElectronNode 的基礎(chǔ)知識,本文只針對 Electron 自動更新機(jī)制進(jìn)行研究。

          目前文中的可行方案僅在 Windows 環(huán)境中適用,MacLinux 環(huán)境的方案亟待研究。

          進(jìn)行了多個方案研究測試,方案簡述如下:利用內(nèi)置的 Squirrel 框架和 ElectronautoUpdater 模塊更新 Electron 應(yīng)用。

          如果您對 Electron 還不是特別清楚,請見我的拙作[《Electron實戰(zhàn)》](https://github.com/qiufeihong2018/vuepress-blog/tree/master/docs/technical-summary/electron_exercise)一文。

          關(guān)鍵詞

          Electron Nsis Squirrel.windows Update.exe

          正文

          一、 背景

          圖 1 Electron

          在開發(fā) xxx 項目的時候,像很多做桌面應(yīng)用的框架(如包括較早的 vc6.0,以及 c#、asp.net、QT、java、Delphi、C++BUILDE 等等)一樣,Electron 需要打包出應(yīng)用程序,分發(fā)給每一個用戶使用。

          二、 當(dāng)前存在的問題

          當(dāng)我們在應(yīng)用中添加了新的功能并且提交了新代碼后,當(dāng)然是希望在用戶的電腦上能夠自動更新。但是最原始的操作是這樣的:

          1. 提交代碼后,用 Webpack 打包混淆代碼,再用 Electron 打包工具打包壓縮代碼,生成可執(zhí)行文件;
          2. 找到打包生成的 exe 等執(zhí)行文件;
          3. 將生成的 exe 發(fā)給用戶,讓用戶重新安裝。

          假如你是用戶,你肯定覺得很煩。不僅是用戶,連開發(fā)者都覺得很煩。有沒有一種方式可以派發(fā)更新,并在用戶的電腦上可以自動更新應(yīng)用呢?答案肯定是有的。

          三、 自動更新的方案

          先來看看,Electron 官網(wǎng)可以提供的幫助。Electron 團(tuán)隊保留 update.electronjs.org,一個免費的開源網(wǎng)絡(luò)服務(wù),Electron 應(yīng)用可以用來自我更新。這個服務(wù)是設(shè)計給那些滿足以下標(biāo)準(zhǔn)的 Electron 應(yīng)用:

          1. 應(yīng)用運(yùn)行在 macOS 或者 Windows;
          2. 應(yīng)用有公開的 GitHub 倉庫;
          3. 編譯的版本發(fā)布在 GitHub Releases
          4. 編譯的版本已代碼簽名。

          使用這個服務(wù)最簡單的方法是安裝 update-electron-app,一個預(yù)配置好的 Node.js 模塊來使用 update.electronjs.org。

          但是 xxx 項目是公司私有項目,根據(jù)公司的網(wǎng)絡(luò)安全規(guī)則,不能將應(yīng)用部署于 GitHub,不能在 GitHub Releases 中公開發(fā)布,所以需要運(yùn)行自己的更新服務(wù)器。

          沒關(guān)系,Electron 團(tuán)隊考慮到這個問題,給出了一些可以私有部署的更新服務(wù)器。方案中的更新服務(wù)器有以下這些:

          1. Hazel——用于私人或開源應(yīng)用的更新服務(wù)器,可以在 Now 上免費部署。它從 GitHub Releases 中拉取更新文件,并且利用 GitHub CDN 的強(qiáng)大性能;
          2. Nuts——同樣使用 GitHub Releases, 但得在磁盤上緩存應(yīng)用程序更新并支持私有存儲庫;
          3. Electron-release-server——提供一個用于處理發(fā)布的儀表板,并且不需要在 GitHub 上發(fā)布;
          4. Nucleus——一個由 Atlassian 維護(hù)的 Electron 應(yīng)用程序的完整更新服務(wù)器。支持多種應(yīng)用程序和渠道,使用靜態(tài)文件存儲來降低服務(wù)器成本。

          官方的這些服務(wù)器經(jīng)過分析,HazelNuts 依賴 GitHub releases 拉取更新文件,所以這兩個不適用。Electron-release-serverNucleus 這兩種經(jīng)過測試是適用的。部署采用 Docker 技術(shù)。部署好后獲得的更新服務(wù)器的地址后面需要使用的。

          部署好更新服務(wù)器后,就可以導(dǎo)入所需要的代碼模塊。下面的代碼只在打包的應(yīng)用程序,而不是開發(fā)中。

          我是通過 app.isPackaged 屬性來區(qū)分開發(fā)和生產(chǎn)的:

          if?(app.isPackaged)?{
          ??require('./update')
          ??getAutoUpdateDep()
          }

          導(dǎo)入依賴:

          const?{?app,?autoUpdater,?dialog?}?=?require('electron')

          下一步, 構(gòu)建更新服務(wù)器的 URL 并且通知 autoUpdater

          const?server?=?'服務(wù)器地址'
          const?url?=?`${server}/update/${process.platform}/?${app.getVersion()}`

          autoUpdater.setFeedURL({?url?})

          作為最后一步,檢查更新。下面的示例將 1 小時檢查一次:

          setInterval(()?=>?{
          ??autoUpdater.checkForUpdates()
          },?3600000)

          應(yīng)用程序被打包后, 它將接收我每次發(fā)布在服務(wù)器上的更新。

          現(xiàn)在已經(jīng)為應(yīng)用程序配置了基本的更新機(jī)制,需要確保在更新時通知用戶。這可以使用autoUpdater API events 來實現(xiàn):

          autoUpdater.on('update-downloaded',?(event,?releaseNotes,?releaseName)?=>?{
          ??const?dialogOpts?=?{
          ????type:?'消息',
          ????buttons:?['重啟',?'稍后'],
          ????title:?'應(yīng)用更新',
          ????message:?process.platform?===?'win32'???releaseNotes?:?releaseName,
          ????detail:?'應(yīng)用已經(jīng)更新了,請重啟'
          ??}

          ??dialog.showMessageBox(dialogOpts).then((returnValue)?=>
          ????if(returnValue.response?===?0)?autoUpdater.quitAnd()
          ??})
          })

          目前,xxx 項目更新的細(xì)致步驟,也就是每次執(zhí)行應(yīng)用程序時,UpdateManager 會執(zhí)行的步驟如下:

          1. 檢查更新。下載發(fā)行版位置的 RELEASES 文件,并與本地 RELEASES 文件進(jìn)行比較,以檢查是否有更新;
          2. 下載并驗證更新包。如果有一個新版本,UpdateManager 決定是下載 deltas 還是最新的完整包(通過計算哪一個需要較少的下載)來更新到當(dāng)前版本。這些包與 RELEASES 文件中的 SHA1 進(jìn)行比較,以進(jìn)行驗證;
          3. Deltas 構(gòu)建完整的包。如果已經(jīng)下載了 delta 包,那么將從以前的完整包和下載的 delta 文件創(chuàng)建一個新的完整包;
          4. 安裝新版本。從完整包中提取當(dāng)前版本的 xxx 項目,并基于版本號(例如 app-1.0.1)將其放在新的 %LocalAppData%\xxx 項目安裝目錄中;
          5. 快捷方式不更新。新 xxx 項目安裝位置替換了原來的 xxx 項目位置,所以快捷方式地址還是舊的;
          6. 前一個版本清理。安裝完成后,用 replace.batxxx 項目新版本替換老版本。(例如更新到 app-1.0.5 后,app-1.0.4 之前全部刪除)。
          7. 目前,沒有內(nèi)置回滾到以前版本的支持。

          有些步驟的具體代碼見第五節(jié)。

          下面是兩種可行的更新服務(wù)器的解決方案以及他們所依賴打包更新機(jī)制。

          (一) Electron-builder搭配Electron-release-server

          對于 Electron-builder 的介紹,官網(wǎng)給得相當(dāng)詳細(xì),一個完整的解決方案,打包和建立準(zhǔn)備分發(fā) Electron 應(yīng)用程序的”auto update”支持開箱即用。下面是 Electron-builderwindows 的兩種配置方式,分別是 Squirrel.windowsNsis,其他的就不提了。

          1. Squirrel.windows 自動更新,該方式默認(rèn)安裝到本地用戶帳戶下,安裝在 %LocalAppData% 下(例如,xxx 項目就會被安裝在 C:\Users\用戶\AppData\Local\xxx 文件夾中),并且會自動產(chǎn)生 packages 文件夾和 Update.exe 程序。packages 包含了版本信息的 RELEASES 文件。如果有最新版本,他的 nupkg 也會下載到其中。期間,自動更新的日志會存放在 SquirrelSetup.log 中。
          2. Nsis 自動更新方式與 Squirrel.windows 類似。但是安裝后不會產(chǎn)生 packages 文件夾和 Update.exe 程序。打開后可以選擇安裝目錄等安裝步驟進(jìn)行安裝,安裝顆粒度變得更加細(xì)致。

          當(dāng)創(chuàng)建項目時,腳手架可以選擇是否集成 Electron-builder,xxx 項目配置參數(shù)如下:

          "build":?{
          ????"win":?{
          ??????"target":?[
          ????????"nsis",
          ????????"zip",
          ????????"squirrel"
          ??????],
          ??????"icon":?"xxx項目.ico",
          ??????"publish":?[
          ????????{
          ??????????"provider":?"generic",
          ??????????"url":?""
          ????????}
          ??????]
          ????},
          ????"squirrelWindows":?{
          ??????"iconUrl":?"https://path/to/valid/image.png"
          ????},
          ????"linux":?{
          ??????"icon":?"build/icons"
          ????},
          ????"nsis":?{
          ??????"oneClick":?false,
          ??????"allowElevation":?true,
          ??????"allowToChangeInstallationDirectory":?true,
          ??????"installerIcon":?"./xxx項目.ico",
          ??????"uninstallerIcon":?"./xxx項目.ico",
          ??????"installerHeaderIcon":?"./xxx項目.ico",
          ??????"createDesktopShortcut":?true,
          ??????"createStartMenuShortcut":?true,
          ??????"perMachine":?false,
          ??????"unicode":?true,
          ??????"deleteAppDataOnUninstall":?false
          ????},
          ????"extends":?null
          ??}

          Electron-builder 打包生成的目錄如下:

          build
          ├─icons
          ├─squirrel-Windows
          ├─xxx?Setup?0.0.1.exe
          ├─xxx?Setup?0.0.2.exe
          ├─xxx?Setup?0.0.3.exe
          ├─xxx-0.0.1-full.nupkg
          ├─xxx-0.0.2-full.nupkg
          ├─xxx-0.0.3-full.nupkg
          └─win-unpacked?
          ????├─libs
          ...需要的依賴
          ????├─locales
          ????├─resources
          ????│??└─app.asar.unpacked
          ????│??????└─node_modules
          ...npm依賴
          ????└─swiftshader
          ├─xxx?Setup?0.0.1.exe
          ├─xxx?Setup?0.0.1.exe.blockmap
          ├─xxx?Setup?0.0.2.exe
          ├─xxx?Setup?0.0.2.exe.blockmap
          ├─xxx?Setup?0.0.3.exe
          ├─xxx?Setup?0.0.3.exe.blockmap
          ├─xxx-0.0.1-win.zip
          ├─xxx-0.0.2-win.zip
          ├─xxx-0.0.3-win.zip
          1. build:打包產(chǎn)生的文件夾;
          2. Nupkg:是具有 .nupkg 擴(kuò)展的單個 ZIP 文件,此擴(kuò)展包含編譯代碼 (Dll)、與該代碼相關(guān)的其他文件以及描述性清單(包含包版本號等信息);
          3. squirrel-Windows:打包方式的產(chǎn)物,包括 exenupkg。區(qū)別于 nsis 打包出來的 exe
          4. win-unpacked:源代碼。

          詳細(xì)補(bǔ)充請見第四節(jié)的打包的兩種方式。

          Electron-release-server 提供一個后臺 Squirrel.windows 自動更新。

          Electron-release-server 將在以下接口提供 NuGet 包:

          1. http://download.myapp.com/update/win32/:version/RELEASES
          2. http://download.myapp.com/update/win64/:version/RELEASES
          3. http://download.myapp.com/update/win32/:version/:channel/RELEASES
          4. http://download.myapp.com/update/win64/:version/:channel/RELEASES
          5. http://download.myapp.com/update/flavor/:flavor/win32/:version/RELEASES
          6. http://download.myapp.com/update/flavor/:flavor/win64/:version/RELEASES
          7. http://download.myapp.com/update/flavor/:flavor/win32/:version/:channel/RELEASES
          8. http://download.myapp.com/update/flavor/:flavor/win64/:version/:channel/RELEASES

          如果未指定通道,然后 stable 將被用。如果 flavor 沒被指定, 那么 default 將被用。如果 win64 備用 但是只有 win32 資產(chǎn)可用,它將被使用。注意:如果需要,可以使用 windows_32 代替 win32 ,使用 windows_64 代替 win64。只要管理 Update.exe 或者 Squirrel.windows 去用 http://download.myapp.com/update/win32/:version/:channel 作為無需 query 的提要 URL。比如,xxx 項目只需要新建一個 version,上傳 .nupkgsetup.exe。

          (二) Electron-forge搭配nucleus

          Nucleus 這一款更新服務(wù)器和上述的服務(wù)器類似,electron-forge 打包跟 Electron-builder 類似,目前只知道它通過 squirrel 方式更新有效,但是它是否能使用 Nsis 安裝配置更新未知。

          期間還調(diào)研了 Electron-packagerElectron-winstallerElectron-updater 的打包自動更新方案,其打包原理大同小異。

          前兩者的方式都是采用 Electron 原生的 autoupdate 方式,將 dist 打包成應(yīng)用程序的方式不同,packager 是一個命令行工具和 Node.js 庫,它將基于 Electron 應(yīng)用程序源代碼、重命名的 Electron 可執(zhí)行文件的和支持文件打包進(jìn)準(zhǔn)備發(fā)布的文件夾中;winstaller 是用于用 Squirrel 構(gòu)建 Electron 應(yīng)用程序成 Windows 安裝程序的 NPM 模塊 。最后一種是對原生 autoupdate 機(jī)制進(jìn)行封裝。

          四、 打包的兩種方式

          如果要談自動更新的話,必須要講講 Electron 的打包。

          (一) Squirrel.windows方式

          squirrel.window吉祥物

          圖 2 squirrel.window吉祥物

          它是一組工具和一個庫,它可以完全管理安裝和更新用任何其他語言編寫的桌面 Windows 應(yīng)用程序。

          Windows 應(yīng)用程序的安裝和更新應(yīng)該和谷歌 Chrome 一樣快、一樣容易。從應(yīng)用程序開發(fā)人員的角度來看,為應(yīng)用創(chuàng)建一個安裝程序并發(fā)布更新應(yīng)該是非常簡單的,而不需要經(jīng)歷一些繁瑣的步驟。正巧,Squirrel.windows 可以解決這一些繁瑣的步驟。

          配置
          1. 為現(xiàn)有的 .NET 應(yīng)用程序集成安裝程序應(yīng)該非常容易;
          2. 客戶端 API 應(yīng)該能夠檢查更新和接收一個(最好是 HTML 格式)更新日志;
          3. 在安裝和更新期間,開發(fā)人員應(yīng)該控制自定義操作和事件;
          4. 卸載給了應(yīng)用程序一個清理的機(jī)會(例如,可以在卸載時運(yùn)行了一段代碼)。
          打包
          1. 對于現(xiàn)有的應(yīng)用程序,生成安裝程序應(yīng)該非常簡單,就像對于 ClickOnce 一樣;
          2. 為我的應(yīng)用程序創(chuàng)建一個更新應(yīng)該是一個非常簡單的過程,很容易自動化;
          3. 打包將支持增量文件,以減少更新包的大小。
          分發(fā)
          1. 托管一個更新服務(wù)器應(yīng)該是非常簡單的,并且應(yīng)該能夠使用簡單的 HTTP 來完成(例如,xxx 項目托管了 electron-release-server);
          2. 支持多種渠道發(fā)布。
          安裝
          1. 安裝到本地用戶帳戶(例如,在 %LocalAppData% 下);
          2. 沒有重新啟動。
          更新
          1. 更新應(yīng)該能夠在應(yīng)用程序運(yùn)行時應(yīng)用;
          2. 任何時候都不應(yīng)該強(qiáng)迫用戶停止他或她正在做的事情;
          3. 沒有重新啟動。

          squirrel.window默認(rèn)安裝

          圖 3 Squirrel.windows 默認(rèn)安裝

          (二) Nsis方式

          全名:Nullsoft Scriptable Install System,是一個開源的 Windows 系統(tǒng)下安裝程序制作程序。它提供了安裝、卸載、系統(tǒng)設(shè)置、文件解壓縮等功能。這如其名字所指出的那樣,NSIS 是通過它的腳本語言來描述安裝程序的行為和邏輯的。NSIS 的腳本語言和通常的編程語言有類似的結(jié)構(gòu)和語法,但它是為安裝程序這類應(yīng)用所設(shè)計的。

          nsis 鍵包含一組選項,指示 Electron-builder 如何構(gòu)建 nsis 目標(biāo)。這些選項也適用于 Web 安裝程序,使用頂級 nsisWeb 密鑰。

          這個要詳細(xì)的講一下,這個 nsis 的配置指的是安裝過程的配置,其實還是很重要的,如果不配置 nsis 那么應(yīng)用程序就會自動的安裝在 C 盤。沒有用戶選擇的余地,這樣肯定是不行的。然后,我就想到一個好主意,要不讓 nsisSquirrel.windows 的結(jié)合產(chǎn)生xxx 項目,既使用 Squirrel.windows 的更新機(jī)制,又使用 nsis 的自定義安裝。

          關(guān)于 nsis 的配置是在 buildnsis 這個選項中進(jìn)行配置,下面是部分 nsis 配置:

          "nsis":?{
          ??"oneClick":?false,?//?是否一鍵安裝
          ??"allowElevation":?true,?//?允許請求提升。?如果為false,則用戶必須使用提升的權(quán)限重新啟動安裝程序。
          ??"allowToChangeInstallationDirectory":?true,?//?允許修改安裝目錄
          ??"installerIcon":?"./build/icons/aaa.ico",//?安裝圖標(biāo)
          ??"uninstallerIcon":?"./build/icons/bbb.ico",//卸載圖標(biāo)
          ??"installerHeaderIcon":?"./build/icons/aaa.ico",?//?安裝時頭部圖標(biāo)
          ??"createDesktopShortcut":?true,?//?創(chuàng)建桌面圖標(biāo)
          ??"createStartMenuShortcut":?true,//?創(chuàng)建開始菜單圖標(biāo)
          ??"shortcutName":?"xxxx",?//?圖標(biāo)名稱
          ??"include":?"build/script/installer.nsh",?//?包含的自定義nsis腳本?這個對于構(gòu)建需求嚴(yán)格得安裝過程相當(dāng)有用。
          }

          關(guān)于 includescript 到底選擇哪一個?在對個性化安裝過程需求并不復(fù)雜,只是需要修改一下安裝位置,卸載提示等等的簡單操作建議使用 include 配置,如果你需要炫酷的安裝過程,建議使用 script 進(jìn)行完全自定義。xxx 項目上傳到服務(wù)器上的就是 nsis 打包出來的 setup.exe。

          nsis自定義安裝

          圖 4 nsis 自定義安裝

          NsisSquirrel.windows 相同之處:

          1. 之前的應(yīng)用程序版本在更新后仍然存在。應(yīng)用程序的舊版本一直存在。
          2. 打包 - 打包應(yīng)用程序文件并準(zhǔn)備發(fā)布。
          3. 安裝 - 初始安裝應(yīng)用程序的過程。

          不同之處:

          1. Nsis 有顆粒度更細(xì)致的安裝。
          2. Nsis 無法生成 packages 文件夾和 Update.exe 程序。
          3. Squirrel.windows 只能安裝在本地用戶帳戶中。
          4. Squirrel.windows 集成 - 將 Squirrel UpdateManager 集成到您的應(yīng)用程序中。分發(fā) - 為用戶提供安裝和更新文件。更新 - 更新現(xiàn)有安裝的過程。

          小結(jié)

          系列一從自動更新的方案深入地講解了其中的原理,另外還講解了兩種打包方式。

          后面的系列,讓我們來看看自動更新開發(fā)中出現(xiàn)的一些問題。

          參考文獻(xiàn)


          [更新應(yīng)用程序](https://www.electronjs.org/docs/tutorial/updates)

          最后,希望大家一定要點贊三連。

          可以閱讀我的其他文章,見[blog地址](https://github.com/qiufeihong2018/vuepress-blog)

          一個學(xué)習(xí)編程技術(shù)的公眾號。每天推送高質(zhì)量的優(yōu)秀博文、開源項目、實用工具、面試技巧、編程學(xué)習(xí)資源等等。目標(biāo)是做到個人技術(shù)與公眾號一起成長。歡迎大家關(guān)注,一起進(jìn)步,走向全棧大佬的修煉之路


          瀏覽 79
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品操逼视频 | 青青草视频在线免费看 | 一级生活毛片 | 国产免费观看av 国产免费无码视频 | 欧美亚洲在线观看 |