需要一个web服务(支持HTTPS)来存放更新包以及对应的更新信息。(个人实验,配置Tomcat支持HTTPS,后来发现http也可以)
winsparkle库的功能是,通过HTTPS检测更新(通过web端的.xml文件的内容,判断web上的版本与当前程序版本的新旧),下载更新包到临时文件夹,打开更新包。
一 获取库
从 https://github.com/vslavik/winsparkle上下载最新代码并编译出WinSparkle.lib和WinSparkle.dll,或者从 https://winsparkle.org/上下载编译好的库;
二 使用库
参照\winsparkle\examples里的两个例子(一个qt工程,一个vs工程)调用相关接口,以qt工程为例,具体如下:
1. 设置软件参数并初始化winsparkle:
见mainwindow.cpp的initWinSparkle(),其中:
win_sparkle_set_appcast_url("https://winsparkle.org/example/appcast.xml");
设置软件更新服务源的url,appcast.xml是一个RSS2.0 feed文件,内容是xml格式,该文件里描述了新版本安装包的信息,包括版本号,发布日志等,当要发布一个新版本时,需要在web服务器上更新这个文件,以便客户端检测是否有新版本发布。
win_sparkle_set_app_details(L"winsparkle.org", L"WinSparkle Qt Example", L"1.0");
设置软件的“元数据”,即一些基本信息,包括公司名称、软件名称、版本号等;
win_sparkle_set_dsa_pub_pem(reinterpret_cast<const char *>(QResource(":/pem/dsa_pub.pem").data()));
设置本软件的公钥;winsparkle提供了数字签名验证机制,当下载了新版本,在安装之前首先对新版本的安装包进行数字签名校验,公钥的作用就是用来校验新版本的安装包的。
win_sparkle_init(); 初始化winsparkle
2. 检查更新
win_sparkle_check_update_with_ui(); 带界面的检查更新接口
win_sparkle_check_update_with_ui_and_install(); 带界面的检查更新接口,若有新版本则在下载完新版本后自动进行安装;
win_sparkle_check_update_without_ui(); 没有界面的检查更新接口(即不显示检测进度),当有新版本时仍会显示新版本信息界面;
3. 下载、安装更新
当下载完后,显示界面
点击安装更新,则会打开下载的更新包。
4. 设置相关回调接口
比较常用的回调有:
win_sparkle_set_can_shutdown_callback(win_sparkle_can_shutdown_callback_t callback); 设置回调查询软件是否能被关闭,当选择开始安装更新包后会调用设置的回调;
win_sparkle_set_shutdown_request_callback(win_sparkle_shutdown_request_callback_t); 设置关闭软件的回调函数,当开始安装更新包后会调用设置的回调接口;
win_sparkle_set_update_cancelled_callback(win_sparkle_update_cancelled_callback_t callback); 设置用户点击了取消下载按钮的回调函数,当在下载新版本过程中取消下载,则会调用设置的回调接口;
PS:我使用Win64OpenSSL_Light-1_1_1a,直接运行generate_keys.bat报错:
gendsa: Use -help for summary.
read DSA key
Can't open dsa_priv.pem for reading, No such file or directory
7572:error:02001002:system library:fopen:No such file or directory:crypto\bio\bss_file.c:72:fopen('dsa_priv.pem','r')
7572:error:2006D080:BIO routines:BIO_new_file:no such file:crypto\bio\bss_file.c:79:
unable to load Private Key
unable to load Key
Failed to create "dsa_priv.pem"!
把脚本修改了下:
openssl gendsa dsaparam.pem -out dsa_priv.pem
==> openssl gendsa -out dsa_priv.pem dsaparam.pem
就成功生成了公钥和私钥。
三 数字签名
需要使用openssl来为软件生成一对密钥,公钥用作客户端软件进行验证更新包,私钥用作生成更新包的数字签名。在winsparkle\bin里提供了生成密钥的脚本generate_keys.bat以及生成数字签名的脚本sign_update.bat。具体使用如下:
- 安装openssl。https://slproweb.com/products/Win32OpenSSL.html
- 使用generate_keys.bat脚本生成密钥dsa_pub.pem和dsa_priv.pem,该操作只需执行一次,作为软件的公、私密钥,妥善保管。
- 把dsa_pub.pem的内容作为win_sparkle_set_dsa_pub_pem()接口的参数传入;
- 使用sign_update.bat来生成数字签名,例如
MEQCIF6Aj9l9qPtxrVRl4pj6VYlMXSmUh2O40sLN9cVKfdnYAiACEEdCYfW4N3vFQzX8YuZ1hdjYjX2ltgJ80cxZX
- 更新web服务器上的appcast.xml文件,把更新包的数字签名填到enclosure节点的sparkle:dsaSignature属性项中
- 更新包放在appcast.xml中enclosure节点的url属性项指明的位置里。