相关文章推荐
帅气的闹钟  ·  Android WebView ...·  9 月前    · 
骑白马的紫菜汤  ·  java 动态加载 ...·  1 年前    · 
淡定的跑步鞋  ·  angular ui tree table-掘金·  1 年前    · 

要说 electron 的自动更新有多难,上篇的版本管理服务器只是开胃菜。真正难啃的是这篇。全文分成 electron 14,electron-updater, electron-builder  三部分。

electron 14

为什么要用 14 版本?因为低于 14 版本用不了 electron-builder 的 NSIS 打包。并且需要把 nodeJs 升级到 12 版本以上。从低版本过来的朋友会发现好多报错,因为 14 做了一篮子改变,改的改删的删, 具体看 Electron 14.0.0 | Electron .

最明显的改变是 remote 的引用方式 。旧版是 require('electron').remote ,而新版把 remote 移到了独立的模块 @electron/remote, 使用前必须在main process 中初始化。

// 替换为:
const { BrowserWindow } = require('@electron/remote')
// 在主进程中:
require('@electron/remote/main').initialize()
// 必须有这句,才能在 renderer process 中使用 remote
require("@electron/remote/main").enable(win.webContents)

安装 @electron/remote

npm install @electron/remote -S

使用方法 详情 重大更改 | Electron

第二个大变是 webview 。原来通过 preload 往网页中注入 js,跟网页共享一个上下文。新版中注入的 js 在单独的上下文,不可跟网页互相调用。

electron-updater

替代 electron 自带的 autoUpdater。后者支持 Squirrel 更新方式,而前者支持 Squirrel、NSIS 等方式。NSIS 有更灵活的可定制性,后面会讲到。根据官方的声明,将来逐步摒弃 Squirrel 转而支持 NSIS. 两者详细差异对比 Auto Update - electron-builder。

两者的 API 大致相同。electron-updater 无需调用 setFeedURL, 而是把 url 写在 package.json.

配置 package.json

修改 url 为版本服务器地址. build 为 top-level 属性。

"build": {
  "win": {
      "publish": {
        "provider": "generic",
        "url": "http://your-domain/update/win",
        "useMultipleRangeRequest": false

加入自动更新代码

const { autoUpdater } = require("electron-updater")
const log = require('electron-log')
// log 初始化,省略
// 检查更新
autoUpdater.logger = log
// 当可更新时在系统通知栏提示
autoUpdater.checkForUpdatesAndNotify()
// 有用户触发安装更新
autoUpdater.quitAndInstall(true, true)

调用 autoUpdater.checkForUpdatesAndNotify() 将检查 http://your-domain/update/win/latest.yml, win 可写成 win32 或 win64,分别代表 32 和 64 位操作系统。有可用更新则自动下载。不想自动下载可设置 autoUpdater.autoDownload = false,然后用 appUpdater.downloadUpdate(cancellationToken) 手动下载。
退出软件时安装新版本。安装包在这里找到 C:\Users\linglq\AppData\Local\fchp-updater\pending。fchp 换成你的 app 的名字。

详细使用方法参考 Auto Update - electron-builder

electron-builder

将 APP 打包成安装包。支持自动更新。选择 NSIS 还可以自定义安装过程。因为实际的项目中需要检测是否安装了某个第三方软件,没有则启动安装,有则忽略。它都能满足。

安装 electron-builder

npm install electron-builder -D

修改 package.json 

  // top-level
  "build": {
    "appId": "appID",
    "win": {
      "target": "nsis",
      "icon": "src/assets/app.ico",
      "publish": {
        "provider": "generic",
        "url": "http://your-domain/update/win",
        "useMultipleRangeRequest": false
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true,
      "perMachine": true,
      "deleteAppDataOnUninstall": true,
      "include": "build/installer.nsh"
    "extraResources": [
        "from": "resources/aria2",
        "to": "aria2"
"script": {
  "pack": "electron-builder --dir",
  "dist": "electron-builder"

对上面的配置逐一讲解。

  • oneClick 当为 true 时不显示安装界面,一键安装。跟常见的安装过程不一样
  • allowToChangeInstallationDirectory 允许用户选择安装路径
  • perMachine 当为 true 时,默认安装目录是 c:\program files ; false 时默认安装目录是 c:\用户\当前用户名\AppData。
  • deleteAppDataOnUninstall 卸载时是否删除数据目录
  • include 自定义的安装脚本。例如检测是否需要安装第三方插件等等
  • extraResources 例如将第三方 exe 文件打包进来,将会安装到 resources 目录下

npm run pack 只生成文件和目录,不打包成 exe
npm run dist 打包成最终的安装文件,以及.blockmap文件

接下来看看是如何做到检测第三方软件的
build/installer.nsh

!macro customInstall
  ReadRegStr $0 HKLM "SOFTWARE\GPL Ghostscript\9.27" "GS_LIB"
  StrCmp $0 "" 0 skip_ghost_script
  File /oname=$PLUGINSDIR\gs927w32.exe "${BUILD_RESOURCES_DIR}\gs927w32.exe"
  ExecWait '"$PLUGINSDIR\gs927w32.exe" /sw'
  skip_ghost_script:
  ReadRegStr $0 HKLM "SOFTWARE\GraphicsMagick\Current" "Version"
  StrCmp $0 "" 0 skip_graphic_magick
  File /oname=$PLUGINSDIR\GraphicsMagick-1.3.33-Q8-win32-dll.exe "${BUILD_RESOURCES_DIR}\GraphicsMagick-1.3.33-Q8-win32-dll.exe"
  ExecWait '"$PLUGINSDIR\GraphicsMagick-1.3.33-Q8-win32-dll.exe" /sw'
  skip_graphic_magick:
!macroend

大抵的意思是 ReadRegStr 读取注册表字段,判断软件是否存在。没有就用 ExecWait 启动安装,并且等待安装完成。有就略过。

第三方 exe、msi 放在 build 目录下。 对于 msi 引用方式稍微改变一下
ExecWait '"msiexec" /i "$PLUGINSDIR\extramsi.msi" /passive'

 更详细的 NSIS 语法看 https://github.com/NSIS-Dev/Documentation/tree/master/Reference

electron-builder 跟 electron-packager 的区别

两者都是将源码打包成  asar 格式。不同的是,前者生产的文件更大。同一份代码,electron-builder 打包出来的程序有 200M,而 electron-packager 只有 100M。相差近一倍。

还有更大的不同在于写文件方面。electron-packager 生成的是绿色包,可在程序所在目录下面任意读写文件。而 electron-builder 不一样,生成的安装包安装到系统以后,不能再程序目录写入文件或新建目录,否则报“权限不足”的错误。那缓存和数据文件应该怎么保存呢?正确的方法是写到用户的数据目录。

const logDir = path.join(app.getPath('userData'), 'logs')
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir, { recursive: true });

以笔者为例,文件保存到了 C:\Users\linglq\AppData\Roaming\fchp\logs

要说 electron 的自动更新有多难,上篇的版本管理服务器只是开胃菜。真正难啃的是这篇。全文分成 electron 14,electron-updater, electron-builder 三部分。electron 14为什么要用 14 版本?因为低于 14 版本用不了 electron-builder 的 NSIS 打包。并且需要把 nodeJs 升级到 12 版本以上。从低版本过来的朋友会发现好多报错,因为 14 做了一篮子改变,改的改删的删, 具体看Electron 14.0.0 |..
网上大部分是通过本地运行Aria2,然后浏览器打开AriaNg(Aria2的一个前端UI界面)。大部分情况下这样不会有什么问题,但是少数情况下会出现各种奇怪的报错。于是基于Electron,整合了AriaNg和Aria2。 当程序打开时Aria2后端自动在计算机后台开启进程,程序关闭时杀死Aria2后台进程,也就表示我们只需要关注软件的使用不用管后台发生了什么。前后端打包在一起,减少了前后端通讯异常的概率。 可搭配油猴脚本不限速下载百度网盘资源,打开新世界大门,详情访问下方GitHub GitHu
因为我也是从零开始接触electron,所以许多不足之处可以提出来多多交流,如有补充万分感谢。 一、项目环境 我这边的框架使用的是electron和vue,因为vue的脚手架插件时有electron编译的,所以不需要自己去写build,非常方便,随便说一句希望以后这种官方合作越来越多。 我这里使用的electron版本是13.0.1,vue的版本还是2.6.11,electron-update的版本是4.3.9 $ npm i electron $ npm i electron-updater
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Ma...
封装(其实整个丢到在app.on(‘ready’)也是可以的,autoUpdater.checkForUpdates() 必须在ready后调用) const { autoUpdater } = require('electron-updater') const { ipcMain } = require('electron') function updater (event) { au...
1.自行创建Electron项目2.安装electron-builder 打包工具yarn add electron-builder或者npm install electron-builder -D并配置package.json{ "name": "demo", "version": "1.1.1", "description": "A minimal Electron applica...
Electron是一种使用JavaScript、HTML和CSS构建跨平台桌面应用程序的开源框架。在Electron应用程序中自动下载的东西通常会被存储在用户的应用程序数据目录下。这个目录的位置取决于操作系统和应用程序的名称。 在Windows操作系统中,这个目录通常是在C:\Users\<user>\AppData\Roaming\<app-name>\下。在Mac OS X中,这个目录通常是在~/.config/<app-name>/下。在Linux系统中,这个目录通常是在~/.config/<app-name>/下。 可以通过在Electron应用程序中使用NodeJS行动中的特殊模块来访问这个目录,比如“app”模块。使用“app.getPath()”方法可以获取用户数据目录的路径。使用“app.getPath('userData')”方法可以获取应用程序数据目录的路径。 总之,Electron自动下载的东西通常被存储在用户的应用程序数据目录下。开发者可以根据需要获取这个目录的路径来访问下载的文件。
// host: 'DATABASE_HOST', // user: 'DATABASE_USERNAME', // password: 'DATABASE_PASSWORD', // database: 'MAIN_DATABASE_NAME' mysql: { adapter: 'sails-mysql', host: '127.0.0.1', port: 3306, user: 'myuser', password: 'mypassword', database: 'electron_release_server' electron 自动更新之路总结(上)版本管理服务器 afeiqiang: 上传文件路径是 files.dirname 指定的,只要有读写的权限就可以 electron 自动更新之路总结(上)版本管理服务器 afeiqiang: mysql 和 session 的配置参照 local.template 给的样板,同时要注释掉其它的数据库配置 electron 自动更新之路总结(上)版本管理服务器 m0_67523500: 哥 我下载了这个版本管理器的源码 但是运行报错 这里的mysql 和 session 怎么写 上传文件保存的路径 可以和后面更新的放 一个latest文件和安装包的路径一样吗 kafka 延时消息处理 zsj0310: 根本没考虑过性能,一两条消息你这么玩还行