Open JChehe opened 7 years ago
超麻烦- -
@907796658 其实对于无需更改主进程代码的『页面』可以通过服务器获取。而主程序升级则可以像有道云笔记等软件一样,通过浏览器打开新版本链接进行下载完整版即可。
是的,目前正在使用这个方案,希望以后会有更简单的electron自动更新的方案吧,目前太难用了
@907796658 我是electron-builder打包,搭配electron-updater实现的自动更新,简单很多
想请教个问题,mac 下,是否可以从别处复制 app.zip到Squirrel.Mac指定的下载目录,然后再触发autoUpdater.quitAndInstall()呢? 这么问主要是想通过其他方式下载 app,然后利用 quitAndInstall 来安装 app。 另外,Squirrel.Mac对应的下载目录在哪儿呢?跟 ShipIt 目录有什么关系吗?我查找了很多 app 的 ShipIt 目录,发现并没有升级时的缓存文件。
@gemmi 不好意思,很久没接触 electron 了。目前不能解决您的问题。
原文链接:Auto-updating apps for Windows and OSX using Electron: The complete guide
2017.11.06 更新:electron-builder 提供了 electron-updater 模块,具体请查阅:《Quick and painless automatic updates in Electron》。
由于我之前也调研了 Electron 的自动更新方面的知识,所以我会在保留原文所有信息的前提下,加入了一些备注(如作者的一些错误信息和补充了我个人的一些认识)。
通过 Electron,你可能只需一眨眼的时间就完成了一个不错的桌面应用,并分发到用户手中。当你觉得自己能像一个侥幸的坏蛋一样轻松时,你可能会意识到你遗漏了一个重要的点:用户如何获取下一个版本呢?甚至该新版本新增了一些优秀的功能。当然,他们能删除后再重新安装该应用,但这难道不蹩脚吗?
快速浏览 Electron 文档 时,你会注意到该文档中含有 auto-updater 模块,它仅仅是另一个框架——Squirrel 的接口。Squirrel 会在背后检测(或你主动触发)是否有新版本、下载新版本,并在你启动或重启应用时自动更新应用。
但悲伤的是:实际实现起来并不是文档上写的这么简单。因为自动更新在 OSX 和 Windows 上的工作方式并不相同(目前并不支持 Linux),并且这两者的文档是分散在多个库(repository)中。我已经花费了大量的时间把该功能实现了。所以我觉得将我所学习到的知识总结成一篇教程是值得的,希望它能节省你的时间。
虽然这里所讲的一切应该均能在 Windows 和 OSX 上运行,但为了减少异议,我先声明我是在 Mac OSX 10.11 上执行的操作,除了为 Windows 系统构建安装包(在虚拟机上)。
如对该篇教程有任何改善或更新的建议,可在 twitter 联系我!
应用打包
在实现自动更新之前,有一个重要的步骤 —— 打包。我假设大多数人已经知道如何通过 electron-packager 实现该操作,但有两件事是时常被忽略的。
package.json
注意 package.json 的额外字段 —— productName、author 和 description,虽然这几个字段并不是打包必备的,但它们会在 Windows 的 Squirrel 安装包中使用到。
为应用执行代码签名(Code-signing)的这部操作并不是自动更新的必备步骤(译者注:也许作者当时的 Electron 版本的自动更新模块不必进行代码签名,但当前版本是必须要进行这部操作的,官方文档中写道:Your application must be signed for automatic updates on macOS. This is a requirement of
Squirrel.Mac
. ),但这是非常可取的操作。对于 OSX,你需要一个 Apple 的开发者认证,然后在 script 字段的pack:osx
替换以下参数即可:--sign='Developer ID Application: My Company Ltd (ABCDEFGH10)'
在 OSX 中,你可以通过 Keychain Access > My Certificates 查看(应用程序 -> 钥匙串 > 我的证书,如果有的话)。
我并没有在 Windows 上执行代码签名这项操作,但你可以看看该主题相关的优秀教程。
对于 Windows,推荐为 electron-packager 传递 version-string 的所有可选参数,如 company name、product name 等。因为一旦我们生成 Windows 的 Squirrel 安装包,该应用就能在 Windows 的『开始』菜单显示正确的元信息(metadata),而不是 Atom 的默认信息。
所以,让我们开始吧!
OSX
在 OSX 中,自动更新是通过 Squirrel.Mac 处理的,它是内置于 Electron 中。这意味着你只需打包你的应用,然后照常运行就好!
恩,其实不完全是。
Squirrel.Mac 的工作方式是通过访问一个你所提供的 API 『路径』(endpoint),判断是否有新版本。如果没有新版本,那么该路径应该返回 HTTP 204。如果有新版本,则它会期待接收一个 HTTP 200、且是 JSON 格式 的响应,其中包含一个 能获取 .zip 文件的 url。
PS:『路径』又称"终点"(endpoint),表示API的具体网址。
在得到该 url 后,Squirrel 会构造一个 application/zip 的请求去访问该 url,下载相应文件,然后触发最终事件(下载完成)让你知道更新包即将安装。对于你来说,所有事情的处理都是自动化的。
如果你不十分确定服务器程序应该长什么样,可看看下面的一个超级小型的 Node.js/Express 服务,假定它的目录结构如下:
基于 Node 的更新服务 package.json
一个简单地、用于测试 Squirrel.Mac 自动更新的 Express 服务器
这将会从本地的文件系统进行分发文件,但这不是理想的处理方式。我的建议是:将这些文件放置在 Amazon S3。
然后你可以在开发环境下,通过 Electron 访问该路径:
http://localhost:3000/updates/latest?v=1.0.1
?v=1.0.1 是你当前应用的版本。
现在你已经拥有了服务器程序和路径了,那么在应用中处理更新操作就十分简单了。
在 Electron 的主进程文件中,引入 auto-updater 模块,然后获取当前系统和应用的版本:
然后配置路径,该路径会因系统(Windows 和 Mac)不同而有所差异(至于原因,会在 Windows 章节看到):
告诉 Electron 到哪里检测新版本
autoUpdater 模块提供了一些事件,你可通过渲染进程触发它们(译者注:通过 IPC 通讯模块),想获取更多信息,可查阅 auto-Updater 文档页面 。相关交互的实现决定取决于你如何处理这些事件(如发生错误等),并通知用户。但你最后一步应该做的是:
将上述语句放在主进程文件后,应用会以新本版的形式重启。赞!
Windows
如你想象的那样,在 Windows 上实现自动更新是通过 Squirrel.Windows。但它的处理方式与 OSX 完全不同。
与 Squirrel.Mac 不同的点在于:Squirrel.Windows 并不需要一个用于检测新版本的 API 路径,它需要的是一个文件服务器,所以你可以简单地将文件拖拽到 Amazon S3 bucket 上。另外,该 Squirrel 更新器并不内置于 Electron,它是一个第三方依赖。这意味着你需要为你所打包的 Windows 应用生成一个安装器,这样它才会包含 Squirrel 更新器。
好消息是:Windows 的安装包和更新器的运行过程顺滑的。因为当你启动 Setup.exe 时,你会发现安装和启动该应用是迅速的。没有无聊的安装向导和一直按“下一步”、最后按“完成”的步骤,不然与大多数 Windows 安装器如出一辙。当然,它也能生成 delta packages,这让你在执行更新时,不必下载整个应用,这真的是一流啊。
译者注:我通过 electron-builder 生成的 Windows 安装包与我们常见的软件安装界面不太一样,他没有安装向导和点击“下一步”,只有一个安装时的 gif 动画(默认的 gif 动画如下图),因此也就没有让用户选择安装路径等权利。也许作者习惯了 Mac 的安装方式(即下面第二幅图),所以会觉得 Windows 的安装包比较繁琐。
Windows 安装时 默认显示的 gif 动画
Mac 常见的安装模式,将“左侧的应用图标”拖拽到“右侧的 Applications”即可
如果你想为 Windows 应用生成常见的、需要点击“下一步”的(即用户可自定义的)安装包,可以通过 NSIS 程序,具体可看这篇教程《[教學]只要10分鐘學會使用 NSIS 包裝您的桌面軟體–安裝程式打包。完全免費。》。当然,前提还是通过 electron-packager 打包程序。
坏消息是(至少对于 Mac 用户):我不能在 OSX 上正确地生成安装包,所以我建议你下载一个 Windows 虚拟机(如 VirtualBox、parallels),并安装 Node.js。
假设你已经配置好并设置了正确的更新源,那么在上述 OSX 章节的代码基础上,还需要处理一些 Squirrel.Windows 事件,这些事件与 OSX 上的不同。你可以查看该 案例。然而,这里提供一个更简单的方式,仅需安装 electron-squirrel-startup npm 模块:
然后在 Electron 的主进程文件顶部添加以下一行语句:
Squirrel.Windows 事件应该被尽早处理,显然,这是要走的路。
最后,为了生成安装包,我们会使用 Atom 的 grunt-electron-installer。为什么它是一个 grunt 插件,而不是一个简单的命令行工具——我不知道,但它就是解决方法。
更新:Electron 团队开发了一个独立的安装器打包工具——electron-winstaller,它拥有与 grunt task 同样的 API
将 Electron-packager 生成的 win32 文件夹打包压缩(zip),然后将其复制到虚拟机上。在该文件夹外(译者注:在解压后),你需要配置 grunt task,该 task 会生成安装包,因此你应该首先安装所有依赖:
假设 Windows 编译后的包放置在一个称为 MyApp-win32-ia32 的文件夹下。下面展示 Gruntfile 的样子:
需要注意的是:如果你想为你的文件和安装包进行代码签名(code-sign)操作,你也需要为该 task 配置提供所有参数。
运行该 grunt task 后,会在 ./dist 目录下产生一堆文件:
你预期看到的与下面类似:
在下一次发布时,该安装器也会自动生成一个 delta packages。
现在进行最简单的一步 —— 拖拽这些文件到 S3 bucket 进行上传。然后 url 指向该文件夹(包含 RELEASES 和 nupkg 文件)。当应用运行在 Windows 系统上时,它会将该 url 设置到 updateFeed 参数上(因为我们在先前的 OSX 章节处已实现)。
注意:目前有一个与安装器的 node-rcedit 模块相关的问题,该模块会在你尝试去修改 .exe 文件的一些元信息和替换默认图标(icon)时抛出错误。你可以在 这里查看该 issue。因此,目前如果你想为安装器文件修改 icon 或为其赋予实际数据,你可能不得不手动地通过 ResHacker 进行修改。
结束语
希望这篇文章能作为一个好的起点,能帮助和服务每一个正在为 Electron 应用实现自动更新的朋友们。如果你发现任何我遗漏的点,或有任何改善的建议,欢迎在 twitter 告诉我!另外,请记住 Electron 是一个快速发展的框架,所以要确保你阅读的是你当前版本的文档。Electron 的 API 也是更新十分频繁的。