一、介绍
因为windows应用一般大家都是从网上下载的,后期版本肯定会更新,那用flutter开发windows应用, 怎么实现应用内版本更新功能了?可以使用auto_updater库, 这个插件允许 Flutter 桌面 应用自动更新自己 (基于 sparkle 和 winsparkle) 地址如下: https://github.com/leanflutter/auto_updater
二、引入
#将此添加到你的软件包的 pubspec.yaml 文件: dependencies: auto_updater: ^0.1.7 #或者 dependencies: auto_updater: git: url: https://github.com/leanflutter/auto_updater.git ref: main
三、使用
3.1、windows使用需要openssl
运行以下命令: 使用 Chocolatey choco install openssl
3.2、生成私钥
#运行以下命令: dart run auto_updater:generate_keys
macOS 准备使用 EdDSA 签名算法进行签名: 输出: A key has been generated and saved in your keychain. Add the `SUPublicEDKey` key to the Info.plist of each app for which you intend to use Sparkle for distributing updates. It should appear like this: <key>SUPublicEDKey</key> <string>pfIShU4dEXqPd5ObYNfDBiQWcXozk7estwzTnF9BamQ=</string> 更改文件 macos/Runner/Info.plist 如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> ... + <key>SUPublicEDKey</key> + <string>bHaXClrRGMmKoKP/3HJnr/jn2ODTRPAM3VZhhkI9ZvY=</string> </dict> </plist>
Windows 准备使用 DSA 签名算法进行签名: 输出: Generated two files: dsa_priv.pem: your private key. Keep it secret and don't share it! dsa_pub.pem: public counterpart to include in youe app. BACK UP YOUR PRIVATE KEY AND KEEP IT SAFE! If you lose it, your users will be unable to upgrade! 命令将为你生成私钥(dsa_priv.pem)及公钥(dsa_pub.pem),请备份你的私钥并确保其安全,并将公钥作为 Windows 资源添加到项目中。 更改文件 windows/runner/Runner.rc 如下: ... +/ +// +// WinSparkle +// +// And verify signature using DSA public key: +DSAPub DSAPEM "../../dsa_pub.pem"
3.3、打包exe
基于flutter_distributor打包,具体使用可以参考如下地址: https://blog.csdn.net/LuoHuaX/article/details/135695911?spm=1001.2014.3001.5501
3.4、获取签名
macOS 运行以下命令:命令后面的目录和文件名根据你的项目进行修改 dart run auto_updater:sign_update dist/1.1.0+2/auto_updater_example-1.1.0+2-macos.zip 输出: sparkle:edSignature="pbdyPt92pnPkzLfQ7BhS9hbjcV9/ndkzSIlWjFQIUMcaCNbAFO2fzl0tISMNJApG2POTkZY0/kJQ2yZYOSVgAA==" length="13400992" 将获得的新签名更新到 appcast.xml 文件 enclosure 节点的 sparkle:edSignature 属性值。
Windows 运行以下命令:命令后面的目录和文件名根据你的项目进行修改 dart run auto_updater:sign_update dist/1.1.0+2/auto_updater_example-1.1.0+2-windows-setup.exe 输出: sparkle:dsaSignature="MEUCIQCVbVzVID7H3aUzAY5znpi+ySZKznkukV8whlMFzKh66AIgREUGOmvavlcg6hwAwkb2o4IqVE/D56ipIBshIqCH8rk=" length="13400992" 将获得的新签名更新到 appcast.xml 文件 enclosure 节点的 sparkle:dsaSignature 属性值。
3.5、部署更新appcast.xml文件
<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle"> <channel> <title>auto_updater_example</title> <description>Most recent updates to auto_updater_example</description> <language>en</language> <item> <title>Version 1.1.0</title> #发行说明-读取html方式(2选1) <sparkle:releaseNotesLink> https://your_domain/your_path/release_notes.html </sparkle:releaseNotesLink> #发行说明-写死方式(2选1) <description> <![CDATA[ <ul> <li>1、新增XX功能</li> <li>2、新增XX功能</li> </ul> ]]> </description> <pubDate>Sun, 16 Feb 2022 12:00:00 +0800</pubDate> #你更新程序的地址 <enclosure url="http://wwww.xxx.com/1.1.0+2/auto_updater_example-1.1.0+2-macos.zip" sparkle:edSignature="pbdyPt92pnPkzLfQ7BhS9hbjcV9/ndkzSIlWjFQIUMcaCNbAFO2fzl0tISMNJApG2POTkZY0/kJQ2yZYOSVgAA==" sparkle:version="1.1.0" sparkle:os="macos" length="13400992" type="application/octet-stream" /> </item> <item> <title>Version 1.1.0</title> #发行说明-读取html方式(2选1) <sparkle:releaseNotesLink> https://your_domain/your_path/release_notes.html </sparkle:releaseNotesLink> #发行说明-写死方式(2选1) <description> <![CDATA[ <ul> <li>1、新增XX功能</li> <li>2、新增XX功能</li> </ul> ]]> </description> <pubDate>Sun, 16 Feb 2022 12:00:00 +0800</pubDate> #你更新程序的地址 <enclosure url="http://www.xx.com/1.1.0+2/auto_updater_example-1.1.0+2-windows.exe" sparkle:dsaSignature="MEUCIQCVbVzVID7H3aUzAY5znpi+ySZKznkukV8whlMFzKh66AIgREUGOmvavlcg6hwAwkb2o4IqVE/D56ipIBshIqCH8rk=" sparkle:version="1.1.0+2" sparkle:os="windows" length="0" type="application/octet-stream" /> </item> </channel> </rss>
3.6、项目更新版本代码
import 'package:auto_updater/auto_updater.dart'; void main() async { // 必须加上这一行。 WidgetsFlutterBinding.ensureInitialized(); //这段代码不一定要放在main文件,除非你想打开应用就检查更新,也可以放到你点击检查更新的页面 String feedURL = 'http://www.xx.com/appcast.xml'; //就是你appcast.xml文件部署的地址 await autoUpdater.setFeedURL(feedURL); await autoUpdater.checkForUpdates(); await autoUpdater.setScheduledCheckInterval(3600); runApp(MyApp()); }
3.7、测试更新
1、先打包一个更新的版本,比如1.0.1+2,然后将程序放到七牛云或者服务器上,获取下载地址, 复制到appcast.xml的<enclosure>标签,还有生成签名,复制到sparkle:dsaSignature标签, 最后将appcast.xml部署到服务器 2、再打包一个老版本,比如1.0.0+1,然后使用 String feedURL = 'http://www.xx.com/appcast.xml'; //就是你appcast.xml文件部署的地址 await autoUpdater.setFeedURL(feedURL); await autoUpdater.checkForUpdates(); await autoUpdater.setScheduledCheckInterval(3600); 这段代码,进行更新测试,具体效果看下面
3.8、实际效果展示