feat ApiClient.cs添加异步下载文件

feat Md5Util.cs添加计算压缩包MD5
fix 修改OTA
This commit is contained in:
wangkaiyi 2024-08-22 16:29:18 +08:00
parent 64cf339683
commit afb91406f0
14 changed files with 222 additions and 73 deletions

View File

@ -21,4 +21,24 @@ public class Md5Util
return hashString.ToString();
}
/// <summary>
/// 计算压缩包md5
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public static string Md5ForZipFile(string filePath)
{
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(filePath))
{
// 计算文件流的哈希值
var hash = md5.ComputeHash(stream);
// 将哈希值转换为字符串格式
var hashString = BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
return hashString;
}
}
}
}

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("MasstransferCommon")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a303714a635d3146132582a2408fc8cf76a69947")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+64cf3396835594f835ea904d6fccf95de4bc3e01")]
[assembly: System.Reflection.AssemblyProductAttribute("MasstransferCommon")]
[assembly: System.Reflection.AssemblyTitleAttribute("MasstransferCommon")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
04161de5d5b7e53625665da3c9aa9d1cc0c406c72bef7aeb16057254b572fd39
24bba642a13e6757b4f3f31fb043b50bb46d2cbfc99854439c2393c381e11be8

View File

@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasstransferInfrastructure"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasstransferCommon", "MasstransferCommon\MasstransferCommon.csproj", "{66C6D73C-BADB-4E28-9C83-E701B019626D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject1", "TestProject1\TestProject1.csproj", "{D26C3A44-62AF-4ACC-B454-51E1098C2C86}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -24,5 +26,9 @@ Global
{66C6D73C-BADB-4E28-9C83-E701B019626D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66C6D73C-BADB-4E28-9C83-E701B019626D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66C6D73C-BADB-4E28-9C83-E701B019626D}.Release|Any CPU.Build.0 = Release|Any CPU
{D26C3A44-62AF-4ACC-B454-51E1098C2C86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D26C3A44-62AF-4ACC-B454-51E1098C2C86}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D26C3A44-62AF-4ACC-B454-51E1098C2C86}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D26C3A44-62AF-4ACC-B454-51E1098C2C86}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -1,45 +1,11 @@
using System.IO.Compression;
using MasstransferCommon.Model.Constant;
using MasstransferCommunicate.Mqtt;
using MasstransferCommon.Utils;
using MasstransferCommunicate.Mqtt.Client;
using MasstransferExporter.OTA.Model;
namespace MasstransferExporter.OTA.Client;
public class OTAClient
{
/// <summary>
/// 订阅OTA更新
/// </summary>
public static async Task ListenOTAUpdateEvent()
{
await MessageQueueHelper.Subscribe(Topics.IssuedOTAPackage, HandleUpdateOTAEvent);
}
/// <summary>
/// 查询OTA更新
/// </summary>
/// <param name="result"></param>
public static async Task QueryOTAUpdate(string result)
{
await MessageQueueHelper.Publish(Topics.QueryOTA, result);
}
/// <summary>
/// OTA更新反馈
/// </summary>
/// <param name="resutl"></param>
public static async Task OTALicenseUpdateEventFeedback(string resutl)
{
await MessageQueueHelper.Publish(Topics.OTAUpgradeFeedback, resutl);
}
private static async Task HandleUpdateOTAEvent(string topic, string license)
{
}
/// <summary>
/// 备份保存重要文件
/// </summary>
@ -47,7 +13,7 @@ public class OTAClient
/// <param name="destinationDir">目标地址</param>
/// <param name="fileExtension">保存文件扩展名</param>
/// <param name="logFileDir">保存文件日志</param>
public void BackupEssentialFiles(string sourceDir, string destinationDir, string[] fileExtension, string logFileDir)
public static void BackupEssentialFiles(string sourceDir, string destinationDir, string[] fileExtension, string logFileDir)
{
try
{
@ -92,7 +58,7 @@ public class OTAClient
/// 恢复重要文件
/// </summary>
/// <param name="logFileDir">重要文件备份日志</param>
public void RecoverCriticalFiles(string logFileDir)
public static void RecoverCriticalFiles(string logFileDir)
{
try
{
@ -121,7 +87,7 @@ public class OTAClient
/// </summary>
/// <param name="sourceDir">源目录地址</param>
/// <param name="zipFilePath">压缩文件保存地址</param>
public void CompressDirectory(string sourceDir, string zipFilePath)
public static void CompressDirectory(string sourceDir, string zipFilePath)
{
try
{
@ -148,7 +114,7 @@ public class OTAClient
/// </summary>
/// <param name="zipFilePath">压缩文件地址</param>
/// <param name="extractPath">解压目录</param>
public void ExtractDirectory(string zipFilePath, string extractPath)
public static void ExtractDirectory(string zipFilePath, string extractPath)
{
try
{
@ -170,7 +136,7 @@ public class OTAClient
/// 删除目录
/// </summary>
/// <param name="sourceDir">删除目录地址</param>
public void DeleteDirectory(string sourceDir)
public static void DeleteDirectory(string sourceDir)
{
if (Directory.Exists(sourceDir))
{
@ -183,11 +149,28 @@ public class OTAClient
/// 删除文件
/// </summary>
/// <param name="sourceDir">删除文件地址</param>
public void DeleteFile(string sourceDir)
public static void DeleteFile(string sourceDir)
{
if (File.Exists(sourceDir))
{
File.Delete(sourceDir);
}
}
/// <summary>
/// 校验安装包
/// </summary>
/// <param name="md5"></param>
public static bool CheckMD5(string md5, string file_path)
{
var file_md5 = Md5Util.Md5ForZipFile(file_path);
if (file_md5.Equals(md5))
{
return true;
}
else
{
return false;
}
}
}

View File

@ -0,0 +1,12 @@
namespace MasstransferExporter.OTA.Model;
public class OTAResultData
{
public byte Result { get; set; }
public string Msg { get; set; }
public string OtaSoftwareVersion { get; set; }
public string CurrentSoftwareVersion { get; set; }
}

View File

@ -0,0 +1,22 @@
using Org.BouncyCastle.Utilities;
namespace MasstransferExporter.OTA.Model;
public class OTAUpdateData
{
public byte Type { get; set; }
public string Url { get; set; }
public string Version { get; set; }
public string Module { get; set; }
public long Size { get; set; }
public string Checksum { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}

View File

@ -1,8 +0,0 @@
namespace MasstransferExporter.OTA.Model;
public class UpdateInfo
{
public bool IsUpdateAvailable { get; set; }
public string Version { get; set; }
public string DownloadUrl { get; set; }
}

View File

@ -1,11 +1,13 @@
using MasstransferExporter.OTA.Client;
using MasstransferCommon.Model.Constant;
using MasstransferCommon.Utils;
using MasstransferCommunicate.Mqtt.Client;
using MasstransferExporter.OTA.Client;
using MasstransferExporter.OTA.Model;
namespace MasstransferExporter.OTA.Service;
public class OTAService
{
private readonly OTAClient _otaClient;
private readonly string _appDir;
private readonly string _criticalBackupDir;
private readonly string _criticalSourceLogPath;
@ -16,7 +18,6 @@ public class OTAService
public OTAService(string appDir, string criticalBackupDir, string criticalSourceLogPath, string[] criticalFileExtension, string previousBackupPath, string updatePackagePath)
{
_otaClient = new OTAClient();
_appDir = appDir;
_criticalBackupDir = criticalBackupDir;
_criticalSourceLogPath = criticalSourceLogPath;
@ -24,12 +25,10 @@ public class OTAService
_previousBackupPath = previousBackupPath;
_updatePackagePath = updatePackagePath;
}
/// <summary>
/// 更新压缩包
/// 安装压缩包
/// </summary>
public void Update()
public void Install()
{
try
{
@ -37,27 +36,27 @@ public class OTAService
initDir();
//备份重要文件
_otaClient.BackupEssentialFiles(_appDir, _criticalBackupDir, _criticalFileExtension, _criticalSourceLogPath);
OTAClient.BackupEssentialFiles(_appDir, _criticalBackupDir, _criticalFileExtension, _criticalSourceLogPath);
//备份旧版本文件
_otaClient.CompressDirectory(_appDir, _previousBackupPath);
OTAClient.CompressDirectory(_appDir, _previousBackupPath);
try
{
//删除旧版本原文件
_otaClient.DeleteDirectory(_appDir);
OTAClient.DeleteDirectory(_appDir);
//解压更新包
_otaClient.ExtractDirectory(_updatePackagePath, _appDir);
OTAClient.ExtractDirectory(_updatePackagePath, _appDir);
//恢复重要文件
_otaClient.RecoverCriticalFiles(_criticalSourceLogPath);
OTAClient.RecoverCriticalFiles(_criticalSourceLogPath);
//删除旧版本备份文件
_otaClient.DeleteFile(_previousBackupPath);
OTAClient.DeleteFile(_previousBackupPath);
//删除更新包
_otaClient.DeleteFile(_updatePackagePath);
OTAClient.DeleteFile(_updatePackagePath);
}
catch (Exception ex)
@ -73,7 +72,7 @@ public class OTAService
//如果重要文件备份已经产生,则删除
if(Directory.Exists(_criticalBackupDir))
{
_otaClient.DeleteDirectory(_criticalBackupDir);
OTAClient.DeleteDirectory(_criticalBackupDir);
}
}
}
@ -104,7 +103,7 @@ public class OTAService
{
if (Directory.Exists(directory))
{
_otaClient.DeleteDirectory(directory);
OTAClient.DeleteDirectory(directory);
}
}
@ -112,15 +111,68 @@ public class OTAService
{
if (File.Exists(file))
{
_otaClient.DeleteFile(file);
OTAClient.DeleteFile(file);
}
}
//恢复旧版本文件
_otaClient.ExtractDirectory(_previousBackupPath, _appDir);
OTAClient.ExtractDirectory(_previousBackupPath, _appDir);
//删除旧版本备份
_otaClient.DeleteFile(_previousBackupPath);
OTAClient.DeleteFile(_previousBackupPath);
}
/// <summary>
/// 订阅OTA更新
/// </summary>
public async Task ListenOTAUpdateEvent()
{
await MessageQueueHelper.Subscribe(Topics.IssuedOTAPackage, HandleUpdateOTAEvent);
}
/// <summary>
/// 查询OTA更新
/// </summary>
/// <param name="request"></param>
public static async Task QueryOTAUpdate()
{
await MessageQueueHelper.Publish(Topics.QueryOTA, null);
}
/// <summary>
/// OTA更新反馈
/// </summary>
/// <param name="resutl"></param>
public async Task OTALicenseUpdateEventFeedback(string resutl)
{
await MessageQueueHelper.Publish(Topics.OTAUpgradeFeedback, resutl);
}
/// <summary>
/// 处理OTA更新
/// </summary>
/// <param name="topic"></param>
/// <param name="otaUpdateData"></param>
private async Task HandleUpdateOTAEvent(string topic, OTAUpdateData otaUpdateData)
{
var type = otaUpdateData.Type;
var url = otaUpdateData.Url;
var version = otaUpdateData.Version;
var module = otaUpdateData.Module;
var size = otaUpdateData.Size;
var checksum = otaUpdateData.Checksum;
var name = otaUpdateData.Name;
var description = otaUpdateData.Description;
//下载更新包
await ApiClient.DownloadFileAsync(url, _updatePackagePath);
//校验压缩包
if(!OTAClient.CheckMD5(checksum, _updatePackagePath)) return;
//启动更新
Install();
}
}

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("MasstransferExporter")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a303714a635d3146132582a2408fc8cf76a69947")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+64cf3396835594f835ea904d6fccf95de4bc3e01")]
[assembly: System.Reflection.AssemblyProductAttribute("MasstransferExporter")]
[assembly: System.Reflection.AssemblyTitleAttribute("MasstransferExporter")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
78895e0730c7e01dfba29760f86535377f37711dd2d831a492fe0a2d3f652707
afb45cd140781d3740c62e8429421ce27af7c578ce7ca503e1181871f13ddf71

View File

@ -68,6 +68,20 @@ public class ApiClient : IDisposable
return await response.Content.ReadFromJsonAsync<T>();
}
/// <summary>
/// 异步请求下载文件
/// </summary>
/// <param name="fileUrl"></param>
/// <param name="destinationFilePath"></param>
public static async Task DownloadFileAsync(string fileUrl, string destinationFilePath)
{
using var response = await Client.GetAsync(fileUrl);
response.EnsureSuccessStatusCode();
using var fileStream = new FileStream(destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
await response.Content.CopyToAsync(fileStream);
}
public void Dispose()
{
Client.Dispose();

View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="NUnit" Version="3.14.0"/>
<PackageReference Include="NUnit.Analyzers" Version="3.9.0"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
</ItemGroup>
<ItemGroup>
<Using Include="NUnit.Framework"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MasstransferCommon\MasstransferCommon.csproj" />
</ItemGroup>
</Project>

20
TestProject1/UnitTest1.cs Normal file
View File

@ -0,0 +1,20 @@
using MasstransferCommon.Utils;
namespace TestProject1;
public class Tests
{
private string file_path = @"C:\Users\wangkaiyi\Downloads\JetBrains2023.1.zip";
private string b = "5181b067ead5386800c291b70b2c9456";
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
var a = Md5Util.Md5ForZipFile(file_path);
Console.WriteLine(a);
}
}