Compare commits
2 Commits
fd52e9c843
...
7ef948ae48
Author | SHA1 | Date |
---|---|---|
wangkaiyi | 7ef948ae48 | |
wangkaiyi | b692f8e41c |
|
@ -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}";
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
namespace MasstransferExporter.StatExporter.Model;
|
||||
|
||||
public class SystemVersion
|
||||
{
|
||||
public string softwareVersion { get; set; }
|
||||
|
||||
public string hardwareVersion { get; set; }
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue