Compare commits

...

2 Commits

Author SHA1 Message Date
wangkaiyi 7ef948ae48 fix OTA完成;
fix 系统版本上传;
2024-09-13 18:13:00 +08:00
wangkaiyi b692f8e41c feat 上行系统版本信息 2024-09-11 20:43:14 +08:00
9 changed files with 220 additions and 64 deletions

View File

@ -120,4 +120,9 @@ public static class Topics
/// 上行系统状态信息 /// 上行系统状态信息
/// </summary> /// </summary>
public const string ReportSystemStat = $"up/{SN}/601/{Version}"; public const string ReportSystemStat = $"up/{SN}/601/{Version}";
/// <summary>
/// 上行系统版本信息
/// </summary>
public const string ReportSystemVersion = $"up/{SN}/602/{Version}";
} }

View File

@ -0,0 +1,32 @@
using System.ComponentModel;
using SQLite;
namespace MasstransferCommon.Model.Entity;
/// <summary>
/// 路径参数
/// </summary>
[Table("path_params"), Description("文件路径参数")]
public class PathParams : Entity
{
[Column("AppDir"), Description("应用程序路径")]
public string AppDir { get; set; }
[Column("AssemblyPath"), Description("程序集路径")]
public string AssemblyPath { get; set; }
[Column("CriticalBackupDir"), Description("重要文件备份目录地址")]
public string CriticalBackupDir { get; set; }
[Column("CriticalFileExtension"), Description("重要文件后缀")]
public string[] CriticalFileExtension { get; set; }
[Column("CriticalSourceLogPath"), Description("重要文件备份记录文件地址")]
public string CriticalSourceLogPath { get; set; }
[Column("PreviousBackupPath"), Description("原应用程序备份目录地址")]
public string PreviousBackupPath { get; set; }
[Column("UpdatePackagePath"), Description("更新包下载地址")]
public string UpdatePackagePath { get; set; }
}

View File

@ -1,4 +1,5 @@
using System.IO.Compression; using System.Diagnostics;
using System.IO.Compression;
using MasstransferCommon.Utils; using MasstransferCommon.Utils;
@ -6,6 +7,10 @@ namespace MasstransferExporter.OTA.Client;
public class OTAClient public class OTAClient
{ {
private const string ProcessName = "Masstransfer";
private const string KeyPath = @""; //待指定
/// <summary> /// <summary>
/// 备份保存重要文件 /// 备份保存重要文件
/// </summary> /// </summary>
@ -168,9 +173,69 @@ public class OTAClient
{ {
return true; return true;
} }
else return false;
{
return false;
}
} }
}
public static bool ExecuteSetup(string packagePath, string appDir)
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = packagePath,
Arguments = "/quiet", // 根据需要添加安装程序的命令行参数
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true // 如果不想显示安装过程窗口
};
try
{
// 启动安装程序
using (Process process = Process.Start(startInfo))
{
if (process != null)
{
// 等待安装程序执行完成
process.WaitForExit();
// 检查返回值通常0表示成功
if (process.ExitCode == 0)
{
Console.WriteLine("安装成功!");
// 在安装成功后执行后续操作
}
else
{
Console.WriteLine($"安装失败,退出代码: {process.ExitCode}");
}
}
}
return true;
}
catch (Exception ex)
{
Console.WriteLine($"执行安装时发生错误: {ex.Message}");
}
return false;
}
public static void startMasstransfer()
{
try
{
//从注册表获取进程路径
if (RegistryHelper.ReadValue(KeyPath, "ExporterPath") is string path)
{
Process.Start(path);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}

View File

@ -2,11 +2,11 @@
public class OTAResultData public class OTAResultData
{ {
public byte Result { get; set; } public byte result { get; set; }
public string Msg { get; set; } public string msg { get; set; }
public string OtaSoftwareVersion { get; set; } public string otaSoftwareVersion { get; set; }
public string CurrentSoftwareVersion { get; set; } public string currentSoftwareVersion { get; set; }
} }

View File

@ -1,16 +0,0 @@
namespace MasstransferExporter.OTA.Model;
public class OTAUpdateFileManager
{
public string UpdatePackagePath;
public string AppDir;
public string CriticalBackupDir;
public string[] CriticalFileExtension;
public string CriticalSourceLogPath;
public string PreviousBackupPath;
}

View File

@ -1,26 +1,43 @@
using MasstransferCommon.Atrributes; using MasstransferCommon.Atrributes;
using MasstransferCommon.Events; using MasstransferCommon.Events;
using MasstransferCommon.Model.Constant; using MasstransferCommon.Model.Constant;
using MasstransferCommon.Utils; using MasstransferCommon.Model.Entity;
using MasstransferCommunicate.Minio;
using MasstransferCommunicate.Mqtt.Client; using MasstransferCommunicate.Mqtt.Client;
using MasstransferCommunicate.Process.Client; using MasstransferCommunicate.Process.Client;
using MasstransferExporter.OTA.Client; using MasstransferExporter.OTA.Client;
using MasstransferExporter.OTA.Model; using MasstransferExporter.OTA.Model;
using MasstransferExporter.StatExporter;
using MasstransferInfrastructure.Database.Sqlite; using MasstransferInfrastructure.Database.Sqlite;
namespace MasstransferExporter.OTA.Service; namespace MasstransferExporter.OTA.Service;
public class OTAService : Instant public class OTAService : Instant
{ {
private static readonly SqliteHelper Db = SqliteHelper.GetInstance(); private static readonly SqliteHelper _sqliteHelper = SqliteHelper.GetInstance();
private static OTAUpdateFileManager _otaUpdateFileManager; private static readonly MinioHelper Minio = MinioHelper.GetInstance();
private static PathParams _filePath;
public static PathParams FilePath
{
get
{
if (_filePath == null)
{
_filePath = _sqliteHelper.Query<PathParams>("select * from path_params limit 1").FirstOrDefault();
if (_filePath == null)
{
throw new Exception("无法从数据库中获取路径参数");
}
}
return _filePath;
}
}
/// <summary> /// <summary>
/// 启动OTA服务 /// 启动OTA服务
/// </summary> /// </summary>
private static async Task StartOTAService(EventType type, bool start) private static async Task StartOTAService(EventType type, bool start)
{ {
_otaUpdateFileManager = GetOTAUpdateFileManager();
//订阅云端发包 //订阅云端发包
await MessageQueueHelper.Subscribe(Topics.IssuedOTAPackage, HandleIssuedOTAPackage); await MessageQueueHelper.Subscribe(Topics.IssuedOTAPackage, HandleIssuedOTAPackage);
@ -36,22 +53,17 @@ public class OTAService : Instant
} }
/// <summary> /// <summary>
/// 从数据库读取文件操作地址、关键文件后缀 /// 处理云端响应OTA请求事件通知Masstransfer
/// </summary> /// </summary>
/// <returns></returns> /// <param name="topic"></param>
private static OTAUpdateFileManager? GetOTAUpdateFileManager() /// <param name="otaUpdateData"></param>
{
return Db.Query<OTAUpdateFileManager>("").FirstOrDefault();
}
private static void HandleIssuedOTAPackage(string topic, OTAUpdateData otaUpdateData) private static void HandleIssuedOTAPackage(string topic, OTAUpdateData otaUpdateData)
{ {
ProcessHelper.Send(ProcessTopics.OTAQueryEventFeedback, otaUpdateData); ProcessHelper.Send(ProcessTopics.OTAQueryEventFeedback, otaUpdateData);
} }
/// <summary> /// <summary>
/// Masstransfer 请求OTA事件响应,向云端发送请求信息 /// 处理Masstransfer请求OTA事件向云端发送请求信息
/// </summary> /// </summary>
/// <param name="topic"></param> /// <param name="topic"></param>
/// <param name="mess"></param> /// <param name="mess"></param>
@ -60,43 +72,51 @@ public class OTAService : Instant
await MessageQueueHelper.Publish(Topics.QueryOTA, new object()); await MessageQueueHelper.Publish(Topics.QueryOTA, new object());
} }
/// <summary>
/// 处理Masstransfer下载安装包事件从云端下载安装包
/// </summary>
/// <param name="topic"></param>
/// <param name="data"></param>
public static async Task HandleDownloadUpdatePackageEvent(string topic, (string Url, string Checksum) data) public static async Task HandleDownloadUpdatePackageEvent(string topic, (string Url, string Checksum) data)
{ {
var updatePackagePath = _otaUpdateFileManager.UpdatePackagePath; var updatePackagePath = FilePath.UpdatePackagePath;
string url = data.Url;
string checksum = data.Checksum; string checksum = data.Checksum;
bool result = false; bool result = false;
var filePath = Path.Combine(updatePackagePath, data.Url.Split("/")[1]);
try try
{ {
await ApiClient.DownloadFileAsync(url, updatePackagePath); await Minio.DownloadFileAsync("cloud", data.Url, filePath);
if (!OTAClient.CheckMD5(checksum, updatePackagePath)) throw new Exception("MD5 check failed."); if (OTAClient.CheckMD5(checksum, filePath))
result = true; {
result = true;
}
} }
catch (Exception e) catch (Exception e)
{ {
Console.WriteLine(e); Console.WriteLine(e);
throw; throw;
} }
ProcessHelper.Send(ProcessTopics.DownloadUpdatePackageEventFeedback, result); ProcessHelper.Send(ProcessTopics.DownloadUpdatePackageEventFeedback, result);
} }
//Masstransfer 通知-启动更新 /// <summary>
private static async Task HandleOTAUpdateEvent(string topic, OTAUpdateData otaUpdateData) /// 处理Masstransfer启动更新事件
/// </summary>
/// <param name="topic"></param>
/// <param name="mess"></param>
private static async Task HandleOTAUpdateEvent(string topic, string mess)
{ {
var version = "";
var otaResultData = new OTAResultData var otaResultData = new OTAResultData
{ {
//启动更新 //启动更新
Result = Install() ? (byte)1 : (byte)0, result = Install() ? (byte)1 : (byte)0,
//restart masstransfer otaSoftwareVersion = mess,
//更新反馈 currentSoftwareVersion = SystemVersionExporter.GetSoftwreVersion()
OtaSoftwareVersion = version,
CurrentSoftwareVersion = version //**需要修改为当前版本
}; };
await MessageQueueHelper.Publish(Topics.OTAUpgradeFeedback, otaResultData); await MessageQueueHelper.Publish(Topics.OTAUpgradeFeedback, otaResultData);
//启动masstransfer
OTAClient.startMasstransfer();
} }
/// <summary> /// <summary>
@ -104,12 +124,13 @@ public class OTAService : Instant
/// </summary> /// </summary>
private static bool Install() private static bool Install()
{ {
var appDir = _otaUpdateFileManager.AppDir; var appDir = FilePath.AppDir;
var criticalBackupDir = _otaUpdateFileManager.CriticalBackupDir; var criticalBackupDir = FilePath.CriticalBackupDir;
var criticalFileExtension = _otaUpdateFileManager.CriticalFileExtension; var criticalFileExtension = FilePath.CriticalFileExtension;
var criticalSourceLogPath = _otaUpdateFileManager.CriticalSourceLogPath; var criticalSourceLogPath = FilePath.CriticalSourceLogPath;
var previousBackupPath = _otaUpdateFileManager.PreviousBackupPath; var previousBackupPath = FilePath.PreviousBackupPath;
var updatePackagePath = _otaUpdateFileManager.UpdatePackagePath; var updatePackagePath = FilePath.UpdatePackagePath;
try try
{ {
//初始化 //初始化
@ -126,8 +147,8 @@ public class OTAService : Instant
//删除旧版本原文件 //删除旧版本原文件
OTAClient.DeleteDirectory(appDir); OTAClient.DeleteDirectory(appDir);
//解压更新包 //安装更新包
OTAClient.ExtractDirectory(updatePackagePath, appDir); OTAClient.ExecuteSetup(updatePackagePath, appDir);
//恢复重要文件 //恢复重要文件
OTAClient.RecoverCriticalFiles(criticalSourceLogPath); OTAClient.RecoverCriticalFiles(criticalSourceLogPath);
@ -170,7 +191,6 @@ public class OTAService : Instant
{ {
Directory.Delete(criticalBackupDir, true); Directory.Delete(criticalBackupDir, true);
} }
Directory.CreateDirectory(criticalBackupDir); Directory.CreateDirectory(criticalBackupDir);
} }
@ -205,6 +225,9 @@ public class OTAService : Instant
//删除旧版本备份 //删除旧版本备份
OTAClient.DeleteFile(previousBackupPath); OTAClient.DeleteFile(previousBackupPath);
//启动masstransfer
OTAClient.startMasstransfer();
} }
public void Initialized() public void Initialized()

View File

@ -2,6 +2,7 @@
using MasstransferCommon.Events; using MasstransferCommon.Events;
using MasstransferCommon.Scheduler; using MasstransferCommon.Scheduler;
using MasstransferCommunicate.Mqtt.Client; using MasstransferCommunicate.Mqtt.Client;
using MasstransferCommunicate.Process.Client;
using MasstransferExporter.DataExporter; using MasstransferExporter.DataExporter;
using MasstransferExporter.Init; using MasstransferExporter.Init;
using MasstransferExporter.StatExporter; using MasstransferExporter.StatExporter;

View File

@ -0,0 +1,8 @@
namespace MasstransferExporter.StatExporter.Model;
public class SystemVersion
{
public string softwareVersion { get; set; }
public string hardwareVersion { get; set; }
}

View File

@ -0,0 +1,38 @@
using System.Runtime.Loader;
using MasstransferCommon.Model.Constant;
using MasstransferCommon.Model.Entity;
using MasstransferCommunicate.Mqtt.Client;
using MasstransferExporter.StatExporter.Model;
using MasstransferInfrastructure.Database.Sqlite;
namespace MasstransferExporter.StatExporter;
/// <summary>
/// 系统版本统计信息
/// 定时触发1d 一次
/// </summary>
public class SystemVersionExporter
{
private static SqliteHelper _sqliteHelper = SqliteHelper.GetInstance();
public static async Task StartVersionExport()
{
var version = new SystemVersion
{
softwareVersion = GetSoftwreVersion(),
hardwareVersion = "1.0.0",
};
await MessageQueueHelper.Publish(Topics.ReportSystemVersion, version);
}
public static string GetSoftwreVersion()
{
var filePath = _sqliteHelper.Query<PathParams>("select * from path_params limit 1").FirstOrDefault();
// 使用 AssemblyLoadContext 动态加载程序集
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(filePath.AssemblyPath);
// 获取程序集的 AssemblyName 对象
var assemblyName = assembly.GetName();
return assemblyName.Version.ToString();
}
}