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

View File

@ -2,6 +2,7 @@
using MasstransferCommon.Events;
using MasstransferCommon.Scheduler;
using MasstransferCommunicate.Mqtt.Client;
using MasstransferCommunicate.Process.Client;
using MasstransferExporter.DataExporter;
using MasstransferExporter.Init;
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();
}
}