📒更新日志
📍2025-02-20 9.1.6
- 修复OSS无需更新的时候直接关闭当前进程。
📍2025-01-13 9.1.5
- 修复LastVersion取值错误问题
📍2025-01-13 9.1.4
- 修复Environment.SetEnvironmentVariable函数带来的执行缓慢问题。
- 在黑名单中添加了以下ClientCore 和 Core共同引用的文件(整个打包、升级流程都不会操作这些文件):
"Microsoft.Bcl.AsyncInterfaces.dll",
"System.Collections.Immutable.dll",
"System.IO.Pipelines.dll",
"System.Text.Encodings.Web.dll",
"System.Text.Json.dll"
📍2025-01-05 9.1.2
-
修复hash校验异常继续执行更新问题
-
解除Common组件和Differential组件与Bowl / ClientCore / Core引用,解决相互升级出现dll占用问题。
-
说明Common和Differential仅存在于GeneralUpdate解决方案中更新迭代,不再更新至Nuget平台。Common组件和Differential组件所有用的能力通过代码文件引用的方式继续存在于Bowl / ClientCore / Core组件中。开发者无需再关心Common和Differential组件是否引用。
📍2025-01-04 9.1.0
- 添加屏蔽指定文件夹跳过功能(指定参数会流转Client、Upgrade)。
- 添加http请求头传入Scheme 和 Token参数。
- 修复OSS Samples 更新失败问题。
- 修改OSS 功能更新完成不删除更新包问题。
- 修复 Samples 中 Client 和 Upgrade 只启动Client更新问题。(出现循环更新的现象是因为没有修改本地版本号)
- 所有Sample 从9.0.0升级库至9.1.0。
📍2024-11-28 9.0.0
-
更新所有组件C#语法均升级至C#13。
-
优化、重构、精简代码,以最少的代码实现功能降低代码阅读难度。
-
简化了GeneralClientBootstrap的传入参数复杂度。
-
移除Strategys参数设置,内置在组件内可自推断所在操作系统平台切换更新策略,开发者无需再关心更新策略设置。
-
新增驱动更新、备份、安装功能。
-
优化了自动升级流程,更新状态的四种工作流:
1.客户端需要升级、升级端需要升级
2.客户端不需要升级、升级端不需要升级
3.客户端不需要升级、升级端需要升级
4.客户端需要升级、升级端不需要升级
-
如果更新失败的版本将会存储在本地,回滚之后再遇到失败版本则跳过更新。
-
GeneralUpdate的OSS功能目前仅支持windows,仅支持zip压缩格式。
-
移除GeneralUpdateOSS通知所有事件。
-
新增GeneralUpdate.Bowl组件
-
GeneralUpdate.Bowl包含回滚、监测、导出dump功能(Only windows,linux会陆续开放)。
-
新增GeneralUpdate.Common组件
-
移除GeneralUpdate.Zip组件
-
移除GeneralUpdate.AspnetCore组件
-
移除MultiDownloadProgressChangedEvent,将该事件的通知内容合并至MultiDownloadStatisticsEvent。
-
移除遗言功能,由GeneralUpdate.Bowl代替。
-
移除7z压缩格式支持,仅支持zip压缩格式。
-
移除ProgressType几种工作模式通知事件参数。
-
移除VersionHub,由UpgradeHubService替代(推送功能)。
-
更新组件内所有Hash值相关校验、生成均为SHA256算法,移除MD5算法。
-
新增更新前备份当前程序所有文件内容。
-
支持Ubuntu操作系统。
-
兼容并支持AOT编译,移除或重构所有不利于AOT编译或使用的代码。
-
所有组件版本号跟随.NET Core的框架版本号。并且统一共享一个版本号,不再各自维护单独的版本号。
-
更新Sample示例更新,使用bat脚本一键生成。
-
修复了若干issue中提出的bug。
-
转移GeneralUpdate.Maui.OSS和GeneralUpdate.OSS类库至新仓库GeneralUpdate.Maui。
-
GeneralUpdate.Differential移除GeneralUpdate.Zip引用,并且移除所有压缩包处理能力。
-
新增升级流程上报服务器升级状态,升级状态为待更新、更新失败、更新成功。
-
重构GeneralUpdate.Tools为Avalonia版本,适配在Linux操作系统上制作差分补丁包。
📍2023-08-05
在企业产品发布到市场之前需要对功能进行测试,在大部分公司里自动升级功能不像产品功能一样有需求文档或者业务说明等文档。通常 的要求就是能正常升级公司产品或能增量更新节约流量即可。这时候对测试经验不足的人员来说测试不充分或者大家都没有考虑到将会造成很多麻烦。(这里只是提供一种测试的思路,并非专业测试指导请辩证看待)
1.测试版本升级顺序
假设市场上所有的客户现在使用的程序版本是v1.0.0.0,我们即将发布v2.0.0.0。在发布之前就需要在测试环境中将两个版本升级测试一下。
- 下载更新包时
- 正在更新文件时
- 强制中断程序运行、断网、直接断电、模拟弱网、模拟崩溃等
2.加密文件无法升级
在GeneralUpdate中在两个版本中提取二进制差分更新补丁文件时,会出现加密文件无法被差分算法识别的情况这个时候需要考虑在生成差分补丁包时,将加密过的文件加入到(SetBlacklist)黑名单中或者考虑直接覆盖(直接打在压缩包里)。
3.失败回滚或者重新升级?
这方面也是企业中大家最在意的一点,自动升级虽然能带来诸多好处。但是升级失败会直接导致客户端根本没法使用这是非常致命的,后续我会考虑在GeneralUpdate中新增两种策略来解决这个问题。
- 策略一
升级之前将需要被更新的文件或目录进行备份,如果更新失败第二次启动则会将备份文件还原至原来的目录,并关闭自动升级的开关以防止文件还原之后再次进行自动升级。
- 策略二
这个是我内心中比较推荐的升级方式,因为自动升级程序的意义就是升级而不是回滚。目前初步的想法是新增遗言机制。为解决在更新时遇到异常情况,导致文件损坏更新的问题。1.每次更新完成,需返回给服务器更新状态。如果客户端在30分钟内没有任何反馈则判定为毁坏性更新失败。(文件损坏)2.升级程序每次 启动时会读取上一次更新的遗言,如果上次更新为失败自动化下载、安装客户端安装包(压缩包)3.或者新增更新守护进程接收实时推送自动化下载、安装客户端安装包(压缩包)
4.项目结构调整
如果开发人员对项目结构发生了一些结构性质的修改。例如基于IoC思想搭建的客户端程序,例如Prism框架如果开发人员把其中的一个Module更换了文件夹的位置或者文件夹名称修改了,导致用户的客户端更新了之后IoC容器启动之后找不到该DLL的异常情况。更新时需要考虑到文件路径变化的问题。测试人员也有责任例行询问是否有该种类的变化。
5.作为最后闭环流程再测试
这个事项是非常需要注意的,如果前面就把自动升级先测试了。如果后续有bug修复或者其他变动都有可能会造成未知的异常情况出现。所以作为最后的闭环流程进行测试是比较推荐的(如有特殊情况按需要调整即可)。
6.弱网环境测试
弱网环境模拟可以借助NetLimiter和Clumsy来进行测试,具体使用方法可以参考我的这篇文章。
7.灰度发布
版本发布之前就需要做好测试。
- 如果面对的客户群体庞大则需要小范围的灰度发布,如果没有问题再选择发布给市场上所有客户。
- 如果是灰度升级版本,这个时候就不要设置为强制更新的版本了。让用户自己选择是否升级。
8.精准升级
在GeneralUpdate中目前已有的基于Signal R接收推送最新版本更新的方式。假设在市场上有很多客户,每个客户有很多台设备。那么其中客户A有10台电脑,只有其中一台电脑因为硬件或者软件环境出现了问题导致客户端的功能异常。这个时候需要紧急针对该台设备的情况进行修复,这个时候并不清楚这个修改会不会对现在已经正常运行的客户端程序有影响。这个时候可以考虑使用一对一的升级方式精准升级某台出问题的电脑。
9.老配置兼容新版本
在市场上如果存在各个分支的版本时,每次自动更新升级还需要考虑到本地配置文件的问题。如果升级到新版本的程序之后需要读配置文件这个时候,老版本的配置文件兼容不了也会造成问题。这个时候测试人员也需要注意该种场景。
规避这种问题的方式可以把大部分容易变动的配置放到服务端每次登录的时候去读取。把不容易变化的配置保存到本地。
10.自动化测试
自动升级的自动测试化测试的脚本编写也非常重要,在多分支、多版本的升级测试中节省时间,增加测试的准确性。
📍2023-07-23
开发者提问:
- (1)在更新过程中出现了断网、断电、电脑死机、突然蓝屏、程序假死等意外情况,导致应用程序无法正常进行更新或者无法正常启动如何解决?能否让更新程序回滚到这次更新之前?
答:这个问题分两块回答,(1)意外情况可以尝试重启应用程序断点下载更新,目前的情况来说如果在更新 过程中出现文件损坏无法只能重新安装。后续会考虑增加一种机制处理更新异常情况无法启动客户端应用程序的问题。(2)不能,因为目前的想法来说自动升级程序的核心意义就是升级,如果回滚回去了升级可能就失去了意义。可能会希望及时发现问题,然后紧急更新一个安全的更新包让客户端逐版本更新直到成功。
- (2)如果更新包打包本身(更新包里本身就有异常文件)就有问题,更新完成之后程序无法正常启动。能不能回滚或者备份?
答:不能,在该版本发布之前就需要做好测试。如果面对的客户群体庞大则需要小范围的灰度发布,如果没有问题再选择发布给市场上所有客户。
- (3)如果客户端本地保存了一些数据文件,在保留之前的数据的文件基础上需要新增一些内容,例如sqlite的.db文件更新之后被之前的.db文件被覆盖,如何解决?或者增量更新是否可以正常更新这些文件?
答:之前有开发过这样的功能,效果不好暂时下线了;后续需要重新设计再启用该类功能。组件目前的功能完成度暂时无法解决这个问题,只能覆盖。增量更新也有极大的可能更新不了这种情况。
📍2023-04-23
使用技术更新
黑名单功能,OSS新功能发布,针对windows和.NET MAUI Android 版本。修复了部分bug和重构了组件整体的事件管理通知机制。
1.发布内容
组件名称 | 版本号(old) | 版本号(new) | 状态 |
---|---|---|---|
GeneralUpdate.AspNetCore | 1.4.1 | - | - |
GeneralUpdate.ClientCore | 2.8.9 | 2.12.9 | 新版本 |
GeneralUpdate.Core | 4.11.18 | 4.14.18 | 新版本 |
GeneralUpdate.Differential | 1.3.0 | 1.4.1 | 新版本 |
GeneralUpdate.Zip | 1.3.0 | - | - |
GeneralUpdate.Tool | 2.2.5 | 2.3.5 | 新版本 |
GeneralUpdate.Single | 1.0.0 | - | - |
GeneralUpdate.Maui.OSS | 1.0.0 | 1.0.0 | 新版本 |
【1】组件GeneralUpdate.ClientCore
1.新增OSS更新功能
2.新增黑名单功能
3.重构事件,添加事件管理机制
4.修复,增量包只能识别新增,不能识别删除
【2】组件GeneralUpdate.Core
1.新增OSS更新功能
2.重构事件,添加事件管理机制
3.修复,增量包只能识别新增,不能识别删除
【3】组件GeneralUpdate.Differential
1.修复,增量包只能识别新增,不能识别删除
2.1 组件GeneralUpdate.ClientCore、组件GeneralUpdate.Core改动
1.事件订阅机制重构之后不再使用event+=订阅方式,通过事件EventManger添加事件监听。对于开发者来说只需要轻微的代码修改即可适应新版本。对于组件本身而言减少大量的代码,组合优于继承。
2.添加黑名单管理SetBlacklist方法,可以设置不想更新的某个具体文件或者某个类型的文件,组件内置默认黑名单文件:Newtonsoft.Json.dll 默认黑名单文件扩展名:.json。
Task.Run(async () =>
{
//ClientStrategy该更新策略将完成1.自动升级组件自更新 2.启动更新组件 3.配置好ClientParameter无需再像之前的版本写args数组进程通讯了。
//generalClientBootstrap.Config(baseUrl, "B8A7FADD-386C-46B0-B283-C9F963420C7C").
var configinfo = GetWindowsConfiginfo();
var generalClientBootstrap = await new GeneralClientBootstrap()
//单个或多个更新包下载通知事件
.AddListenerMultiDownloadProgress(OnMultiDownloadProgressChanged)
//单个或多个更新包下载速度、剩余下载事件、当前下载版本信息通知事件
.AddListenerMultiDownloadStatistics(OnMultiDownloadStatistics)
//单个或多个更新包下载完成
.AddListenerMultiDownloadCompleted(OnMultiDownloadCompleted)
//完成所有的下载任务通知
.AddListenerMultiAllDownloadCompleted(OnMultiAllDownloadCompleted)
//下载过程出现的异常通知
.AddListenerMultiDownloadError(OnMultiDownloadError)
//整个更新过程出现的任何问题都会通过这个事件通知
.AddListenerException(OnException)
.Config(configinfo)
.Option(UpdateOption.DownloadTimeOut, 60)
.Option(UpdateOption.Encoding, Encoding.Default)
.Option(UpdateOption.Format, Format.ZIP)
.Strategy<WindowsStrategy>()
//注入一个func让用户决定是否跳过本次更新,如果是强制更新则不生效
.SetCustomOption(ShowCustomOption)
//默认黑名单文件:{ "Newtonsoft.Json.dll" } 默认黑名单文件扩展名:{ ".patch", ".7z", ".zip", ".rar", ".tar" , ".json" }
//如果不需要扩展,需要重新传入黑名单集合来覆盖。
.SetBlacklist(GetBlackFiles(), GetBlackFormats())
.LaunchTaskAsync();
});
1.新增OSS功能
OSS的全称是对象存储服务(Object Storage Service),做服务端技术栈开发的小伙伴肯定对这个不陌生在各大云服务器厂商都会提供类似的服务,说简单点就是一个文件服务器。例如:阿里云OSS、腾讯云COS、华为云OBS,其实它们只是名字不一样功能服务都差不多。然后本更新组件新功能的实现思路非常相似那么就选择了OSS来为该功能命名,而且方便开发者一眼能get到这个功能的作用(需要使用组件GeneralUpdate.ClientCore、GeneralUpdate.Core)。
2.GeneralUpdate.OSS运行原理
1.准备version.json版本信息配置文件,更新文件(update.zip )更新文件和之前的打包方式一样。
[
{
"PubTime": 1680443321,
"Name": "generalupdate.ossclient",
"MD5": "9bf414990a67e74f11752d03f49b15d8",
"Version": "1.0.4",
"Url": "http://192.168.50.203/update.zip"
},
{
"PubTime": 1680444916,
"Name": "generalupdate.ossclient",
"MD5": "JXC122DFXCZXZNMRFf11752d03f49b15d8",
"Version": "1.0.5",
"Url": "http://192.168.50.203/update2.zip"
}
]
2.Client启动时直接请求OSS服务器或文件服务器,下载version.json文件。
3.下载到本地之后解析版本信息内容判断是否需要更新,如果将信息通过进程启动传递Upgrade(Client自我关闭)。
4.Upgrade启动之后直接去下载update.zip,下载到本地之后直接解压覆盖本地文件。
5.Upgrade更新完成之后把Client启动起来,自我关闭。更新结束。
GeneralUpdateOSS的功能和GeneralUpdateBootstrap功能对比来说,使用的门槛非常低如果公司对自动更新的要求不高的话可以使用这个功能。一句话概括这个功能就是下载version.json根据文件里的内容去逐版本下载更新包,下载下来之后直接解压更新就结束了。
3.快速启动
Client(主客户端)使用代码示例:
Task.Run(async () =>
{
var url = "http://192.168.50.203";
var appName = "GeneralUpdate.Client";
var version = "1.0.0.0";
var versionFileName = "version.json";
ParamsOSS @params = new ParamsOSS(url, appName, version, versionFileName);
await GeneralClientOSS.Start(@params);
});
Upgrade(升级助手)使用代码示例:
private static void Main(string[] args)
{
Task.Run(async () =>
{
//var url = "http://192.168.50.203";
//var appName = "GeneralUpdate.Client";
//var version = "1.0.0";
//var versionFileName = "version.json";
//SerializeUtil.Deserialize<ParamsOSS>(args[0]);
//ParamsOSS @params = new ParamsOSS(url, appName, version, versionFileName);
ParamsOSS @params = SerializeUtil.Deserialize<ParamsOSS>(args[0]);
await GeneralUpdateOSS.Start<OSSStrategy>(@params,Encoding.Default);
});
}
4.事件通知订阅
在OSS的更新过程中,保留了更新事件的参数和之前一样。
//code...
GeneralUpdateOSS.AddListenerMultiDownloadStatistics(OnMultiDownloadStatistics);
private static void OnMultiDownloadStatistics(object sender, MultiDownloadStatisticsEventArgs e)
{
Console.WriteLine($" {e.Speed} , {e.Remaining.ToShortTimeString()}");
}
2.3 .NET MAUI OSS
MAUI OSS功能介绍和 11.OSS中介绍的是一样的。但是它是针对.NET MAUI编写的更新,使用的组件库是GeneralUpdate.Maui.OSS。目前只实现了MAUI Andorid平台的自动更新。
1.准备version.json版本信息配置文件,更新文件(update.apk)更新文件就直接是新版本的apk了(或.abb)。
{
"PubTime": 1680444916,
"Name": "com.companyname.generalupdate.ossclient",
"MD5": "9bf414990a67e74f11752d03f49b15d8",
"Version": "1.0.5",
"Url": "http://192.168.50.203/com.companyname.generalupdate.ossclient.apk"
}
2.Client启动时直接请求OSS服务器或文件服务器,下载version.json文件。
3.下载到本地之后解析版本信息内容,判断是否需要更新。
4.需要更新则下载update.apk。
5.下载完成之后执行安装,这一步就交给了安卓操作系统执行。执行完成之后运行新版本app。
2.快速启动
//http://192.168.50.203/version.json
string url = "http://192.168.50.203";
string appName = "MainApplication.exe";
string currentVersion = "1.1.1.1";
string versionFileName = "versions.json";
GeneralUpdateOSS.AddListenerDownloadProcess(OnOSSDownload);
GeneralUpdateOSS.AddListenerException(OnException);
await GeneralUpdateOSS.Start<Strategy>(new ParamsAndroid(url, appName, "123456789", currentVersion, versionFileName));
3.事件通知订阅
GeneralUpdateOSS.AddListenerDownloadProcess(OnOSSDownload);
GeneralUpdateOSS.AddListenerException(OnException);
private void OnOSSDownload(object sender, OSSDownloadArgs e)
{
Console.WriteLine($"{e.ReadLength},{e.TotalLength}");
}
private void OnException(object sender, ExceptionEventArgs exception)
{
Console.WriteLine(exception.Exception.Message);
}
- .NET MAUI Android 相关疑问处理引导文章
https://www.cnblogs.com/MASA/p/16612541.html
https://learn.microsoft.com/zh-cn/dotnet/maui/android/deployment/?view=net-maui-7.0
https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted
https://note.youdao.com/ynoteshare/mobile.html?id=5c5d5cf8fe1d67419b09024255ff239c
5.运行效果
目前已运行测试机型、平台 。
1.在华为荣耀Px30非鸿蒙系统手机可运行。
2.Visual studio 2022 preview Pixe 5 - API33 (Android 13.0 - API 33) 可运行。
📍2023-01-17
开源项目调整
在github和gitee的两个开源平台分别建立了General开源组织,会将具有一定代码贡献的小伙伴邀请到组织中来并分配奖励。
将原有的GeneralUpdate 拆分成了三个项目,分别是: