1
This commit is contained in:
parent
dce9f31aae
commit
11cdcf9110
@ -4,6 +4,8 @@ VisualStudioVersion = 17.13.35731.43
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoUpdate", "AutoUpdate\AutoUpdate.csproj", "{7851792C-7CFE-4748-A712-974AE110E2D3}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoUpdate", "AutoUpdate\AutoUpdate.csproj", "{7851792C-7CFE-4748-A712-974AE110E2D3}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoUpdateServer", "AutoUpdateServer\AutoUpdateServer.csproj", "{1BDC940C-E1EC-4D8F-A374-CC360C52EEBB}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -14,6 +16,10 @@ Global
|
|||||||
{7851792C-7CFE-4748-A712-974AE110E2D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7851792C-7CFE-4748-A712-974AE110E2D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7851792C-7CFE-4748-A712-974AE110E2D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7851792C-7CFE-4748-A712-974AE110E2D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7851792C-7CFE-4748-A712-974AE110E2D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7851792C-7CFE-4748-A712-974AE110E2D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1BDC940C-E1EC-4D8F-A374-CC360C52EEBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1BDC940C-E1EC-4D8F-A374-CC360C52EEBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1BDC940C-E1EC-4D8F-A374-CC360C52EEBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1BDC940C-E1EC-4D8F-A374-CC360C52EEBB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@ -2,8 +2,73 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="clr-namespace:AutoUpdate"
|
xmlns:local="clr-namespace:AutoUpdate"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
StartupUri="MainWindow.xaml">
|
StartupUri="MainWindow.xaml">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Fonts.xaml" />
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
|
||||||
|
<materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="DeepPurple" SecondaryColor="Lime" />
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" />
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Flyout.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="HighlightBrush" Color="{DynamicResource Primary700}"/>
|
||||||
|
<SolidColorBrush x:Key="AccentBaseColorBrush" Color="{DynamicResource Primary600}" />
|
||||||
|
<SolidColorBrush x:Key="AccentColorBrush" Color="{DynamicResource Primary500}"/>
|
||||||
|
<SolidColorBrush x:Key="AccentColorBrush2" Color="{DynamicResource Primary400}"/>
|
||||||
|
<SolidColorBrush x:Key="AccentColorBrush3" Color="{DynamicResource Primary300}"/>
|
||||||
|
<SolidColorBrush x:Key="AccentColorBrush4" Color="{DynamicResource Primary200}"/>
|
||||||
|
<SolidColorBrush x:Key="WindowTitleColorBrush" Color="{DynamicResource Primary700}"/>
|
||||||
|
<SolidColorBrush x:Key="AccentSelectedColorBrush" Color="{DynamicResource Primary500Foreground}"/>
|
||||||
|
<LinearGradientBrush x:Key="ProgressBrush" EndPoint="0.001,0.5" StartPoint="1.002,0.5">
|
||||||
|
<GradientStop Color="{DynamicResource Primary700}" Offset="0"/>
|
||||||
|
<GradientStop Color="{DynamicResource Primary300}" Offset="1"/>
|
||||||
|
</LinearGradientBrush>
|
||||||
|
<SolidColorBrush x:Key="CheckmarkFill" Color="{DynamicResource Primary500}"/>
|
||||||
|
<SolidColorBrush x:Key="RightArrowFill" Color="{DynamicResource Primary500}"/>
|
||||||
|
<SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{DynamicResource Primary500Foreground}"/>
|
||||||
|
<SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{DynamicResource Primary500}" Opacity="0.4"/>
|
||||||
|
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.OnSwitchBrush.Win10" Color="{DynamicResource Primary500}" />
|
||||||
|
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.OnSwitchMouseOverBrush.Win10" Color="{DynamicResource Primary400}" />
|
||||||
|
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.ThumbIndicatorCheckedBrush.Win10" Color="{DynamicResource Primary500Foreground}" />
|
||||||
|
|
||||||
|
<FontFamily x:Key="misans">pack://application:,,,/Lmes;component/字体/MiSans-Normal.ttf#misans</FontFamily>
|
||||||
|
|
||||||
|
<Style TargetType ="{x:Type Button}" BasedOn="{StaticResource MaterialDesignRaisedButton}">
|
||||||
|
<Setter Property ="FontFamily" Value = "{StaticResource misans}" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType ="{x:Type Label}" BasedOn="{StaticResource MaterialDesignLabel}">
|
||||||
|
<Setter Property ="FontFamily" Value = "{StaticResource misans}" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType ="{x:Type TextBox}" BasedOn="{StaticResource MaterialDesignTextBox}">
|
||||||
|
<Setter Property ="FontFamily" Value = "{StaticResource misans}" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType ="{x:Type PasswordBox}" BasedOn="{StaticResource MaterialDesignPasswordBox}">
|
||||||
|
<Setter Property ="FontFamily" Value = "{StaticResource misans}" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType ="{x:Type ComboBox}" BasedOn="{StaticResource MaterialDesignComboBox}">
|
||||||
|
<Setter Property ="FontFamily" Value = "{StaticResource misans}" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType ="{x:Type GroupBox}" BasedOn="{StaticResource MaterialDesignGroupBox}">
|
||||||
|
<Setter Property ="FontFamily" Value = "{StaticResource misans}" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType ="{x:Type TabControl}" BasedOn="{StaticResource MaterialDesignTabControl}">
|
||||||
|
<Setter Property ="FontFamily" Value = "{StaticResource misans}" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType ="{x:Type TabItem}" BasedOn="{StaticResource MaterialDesignTabItem}">
|
||||||
|
<Setter Property ="FontFamily" Value = "{StaticResource misans}" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType ="{x:Type ScrollViewer}" BasedOn="{StaticResource MaterialDesignScrollViewer}">
|
||||||
|
<Setter Property ="VerticalScrollBarVisibility" Value = "Auto" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using System.Reflection;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
[assembly: ThemeInfo(
|
[assembly: ThemeInfo(
|
||||||
|
|||||||
@ -8,4 +8,11 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MahApps.Metro" Version="3.0.0-alpha0513" />
|
||||||
|
<PackageReference Include="MaterialDesignColors" Version="5.2.2-ci900" />
|
||||||
|
<PackageReference Include="MaterialDesignThemes" Version="5.2.2-ci900" />
|
||||||
|
<PackageReference Include="MaterialDesignThemes.MahApps" Version="5.2.2-ci900" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
102
AutoUpdate/AutoUpdate/LmesApi.cs
Normal file
102
AutoUpdate/AutoUpdate/LmesApi.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using Path = System.IO.Path;
|
||||||
|
|
||||||
|
namespace AutoUpdate
|
||||||
|
{
|
||||||
|
public class LmesApi
|
||||||
|
{
|
||||||
|
public readonly HttpClient httpClient = new();
|
||||||
|
public LmesApi(string 基地址)
|
||||||
|
{
|
||||||
|
httpClient.BaseAddress = new Uri(基地址);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 更新程序
|
||||||
|
public async Task<string> 更新客户端程序()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 获取当前版本信息(从程序集或配置文件中读取)
|
||||||
|
var versionManager = new VersionManager();
|
||||||
|
var currentVersion = versionManager.GetCurrentVersion();
|
||||||
|
|
||||||
|
// 检查最新版本
|
||||||
|
var latestVersion = await 获取最新版本();
|
||||||
|
if (latestVersion == null || latestVersion.Version == currentVersion)
|
||||||
|
{
|
||||||
|
return currentVersion; // 无需更新
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载新版本
|
||||||
|
var downloadPath = await 下载新版本(latestVersion);
|
||||||
|
if (string.IsNullOrEmpty(downloadPath))
|
||||||
|
{
|
||||||
|
throw new Exception("下载更新包失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证下载文件的CRC
|
||||||
|
if (!VerifyCRC(downloadPath, latestVersion.CRC))
|
||||||
|
{
|
||||||
|
throw new Exception("文件校验失败,可能已损坏");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用新的更新管理器
|
||||||
|
var updater = new UpdateManager();
|
||||||
|
await updater.ExtractAndUpdate(downloadPath, latestVersion.Version);
|
||||||
|
return latestVersion.Version;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// 记录错误日志
|
||||||
|
//日志写入.写入($"更新失败: {ex.Message}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<VersionInfo> 获取最新版本()
|
||||||
|
{
|
||||||
|
var response = await httpClient.GetAsync("api/自动更新/获取最新版本信息");
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return await response.Content.ReadFromJsonAsync<VersionInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> 下载新版本(VersionInfo versionInfo)
|
||||||
|
{
|
||||||
|
var downloadPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Updates", versionInfo.FileName);
|
||||||
|
|
||||||
|
using var response = await httpClient.GetAsync($"api/自动更新/下载指定版本/{versionInfo.FileName}");
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var fileStream = new FileStream(downloadPath, FileMode.Create);
|
||||||
|
await response.Content.CopyToAsync(fileStream);
|
||||||
|
|
||||||
|
return downloadPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool VerifyCRC(string filePath, string expectedCRC)
|
||||||
|
{
|
||||||
|
using var fs = System.IO.File.OpenRead(filePath);
|
||||||
|
using var sha = System.Security.Cryptography.SHA256.Create();
|
||||||
|
var hash = sha.ComputeHash(fs);
|
||||||
|
var actualCRC = BitConverter.ToString(hash).Replace("-", "");
|
||||||
|
|
||||||
|
return string.Equals(actualCRC, expectedCRC, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
public class VersionInfo
|
||||||
|
{
|
||||||
|
public string Version { get; set; }
|
||||||
|
public string CRC { get; set; }
|
||||||
|
public string FileName { get; set; }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,12 +1,13 @@
|
|||||||
<Window x:Class="AutoUpdate.MainWindow"
|
<mah:MetroWindow x:Class="AutoUpdate.MainWindow"
|
||||||
|
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
|
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:AutoUpdate"
|
xmlns:local="clr-namespace:AutoUpdate"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="MainWindow" Height="450" Width="800">
|
Title="MainWindow" Height="450" Width="800" Loaded="MetroWindow_Loaded">
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</mah:MetroWindow>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Text;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
@ -8,16 +9,47 @@ using System.Windows.Media;
|
|||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using System.Windows.Navigation;
|
using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
using MahApps.Metro.Controls;
|
||||||
|
using Path = System.IO.Path;
|
||||||
|
|
||||||
namespace AutoUpdate;
|
namespace AutoUpdate;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for MainWindow.xaml
|
/// Interaction logic for MainWindow.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : MetroWindow
|
||||||
{
|
{
|
||||||
|
private LmesApi lmesApi;
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
lmesApi = new LmesApi(系统参数.设置.Lmes连接参数.LMES地址);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MetroWindow_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
_ = 自动更新程序();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task 自动更新程序()
|
||||||
|
{
|
||||||
|
var 本地目录 = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
var 临时更新目录 = Path.Combine(本地目录, "Updates");
|
||||||
|
|
||||||
|
// 确保临时更新目录存在
|
||||||
|
if (!Directory.Exists(临时更新目录))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(临时更新目录);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Title = "当前版本信息:" + await lmesApi.更新客户端程序();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// 更新失败,但允许程序继续运行
|
||||||
|
//日志写入.写入($"检查更新失败: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
130
AutoUpdate/AutoUpdate/UpdateManager.cs
Normal file
130
AutoUpdate/AutoUpdate/UpdateManager.cs
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace AutoUpdate
|
||||||
|
{
|
||||||
|
public class UpdateManager
|
||||||
|
{
|
||||||
|
private readonly string _programPath;
|
||||||
|
private readonly string _updatePath;
|
||||||
|
private readonly string _backupPath;
|
||||||
|
private readonly VersionManager _versionManager;
|
||||||
|
|
||||||
|
public UpdateManager()
|
||||||
|
{
|
||||||
|
// 程序主目录
|
||||||
|
_programPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
// 更新文件夹
|
||||||
|
_updatePath = Path.Combine(_programPath, "Update");
|
||||||
|
// 备份文件夹
|
||||||
|
_backupPath = Path.Combine(_programPath, "Backup");
|
||||||
|
_versionManager = new VersionManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExtractAndUpdate(string zipPath, string newVersion)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 准备更新目录
|
||||||
|
if (Directory.Exists(_updatePath))
|
||||||
|
Directory.Delete(_updatePath, true);
|
||||||
|
Directory.CreateDirectory(_updatePath);
|
||||||
|
|
||||||
|
// 解压新版本到更新目录
|
||||||
|
await Task.Run(() => ZipFile.ExtractToDirectory(zipPath, _updatePath));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 创建更新批处理文件
|
||||||
|
string batchContent = @"
|
||||||
|
@echo off
|
||||||
|
:: 等待原程序退出
|
||||||
|
timeout /t 1 /nobreak
|
||||||
|
|
||||||
|
:: 复制新文件
|
||||||
|
xcopy /Y /E ""%~dp0Update\*.*"" ""%~dp0.""
|
||||||
|
|
||||||
|
:: 删除更新文件夹
|
||||||
|
rd /S /Q ""%~dp0Update""
|
||||||
|
|
||||||
|
:: 清理 Updates 文件夹
|
||||||
|
if exist ""%~dp0Updates"" (
|
||||||
|
rd /S /Q ""%~dp0Updates""
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 启动程序
|
||||||
|
start """" ""%~dp0LMES.exe""
|
||||||
|
|
||||||
|
:: 删除自身
|
||||||
|
del ""%~f0""
|
||||||
|
";
|
||||||
|
|
||||||
|
string batchPath = Path.Combine(_programPath, "update.bat");
|
||||||
|
await File.WriteAllTextAsync(batchPath, batchContent);
|
||||||
|
|
||||||
|
// 启动更新批处理并退出程序
|
||||||
|
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = batchPath,
|
||||||
|
UseShellExecute = true,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
Verb = "runas", // 请求管理员权限
|
||||||
|
};
|
||||||
|
Process.Start(startInfo);
|
||||||
|
// 更新版本文件
|
||||||
|
_versionManager.UpdateVersion(newVersion);
|
||||||
|
// 退出应用程序
|
||||||
|
Application.Current.Shutdown();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception($"更新失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VersionManager
|
||||||
|
{
|
||||||
|
private readonly string _versionFilePath;
|
||||||
|
|
||||||
|
public VersionManager()
|
||||||
|
{
|
||||||
|
_versionFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "version.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetCurrentVersion()
|
||||||
|
{
|
||||||
|
// First try to read from version file
|
||||||
|
if (File.Exists(_versionFilePath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return File.ReadAllText(_versionFilePath).Trim();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//日志写入.写入($"读取版本文件失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to assembly version if file doesn't exist
|
||||||
|
return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateVersion(string newVersion)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(_versionFilePath, newVersion);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//日志写入.写入($"写入版本文件失败: {ex.Message}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
AutoUpdate/AutoUpdate/系统参数.cs
Normal file
23
AutoUpdate/AutoUpdate/系统参数.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AutoUpdate
|
||||||
|
{
|
||||||
|
public class 系统参数
|
||||||
|
{
|
||||||
|
public static 设置类 设置 { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class 设置类
|
||||||
|
{
|
||||||
|
public Lmes连接参数类 Lmes连接参数 { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Lmes连接参数类
|
||||||
|
{
|
||||||
|
public string LMES地址 { get; set; } = @"http://127.0.0.1:5000/";
|
||||||
|
}
|
||||||
|
}
|
||||||
14
AutoUpdate/AutoUpdateServer/AutoUpdateServer.csproj
Normal file
14
AutoUpdate/AutoUpdateServer/AutoUpdateServer.csproj
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.23.0-beta1" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
6
AutoUpdate/AutoUpdateServer/AutoUpdateServer.http
Normal file
6
AutoUpdate/AutoUpdateServer/AutoUpdateServer.http
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@AutoUpdateServer_HostAddress = http://localhost:5062
|
||||||
|
|
||||||
|
GET {{AutoUpdateServer_HostAddress}}/weatherforecast/
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
||||||
133
AutoUpdate/AutoUpdateServer/Controllers/自动更新Controller.cs
Normal file
133
AutoUpdate/AutoUpdateServer/Controllers/自动更新Controller.cs
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using Microsoft.AspNetCore.Cors;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Lmes服务端.Controllers
|
||||||
|
{
|
||||||
|
// 版本信息模型
|
||||||
|
public class VersionInfo
|
||||||
|
{
|
||||||
|
public string Version { get; set; }
|
||||||
|
public string CRC { get; set; }
|
||||||
|
public string FileName { get; set; }
|
||||||
|
}
|
||||||
|
[EnableCors("AllowAll")]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class 自动更新Controller : ControllerBase
|
||||||
|
{
|
||||||
|
private string 存储路径 { get; set; }
|
||||||
|
|
||||||
|
public 自动更新Controller()
|
||||||
|
{
|
||||||
|
// 设置版本文件存储路径
|
||||||
|
存储路径 = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||||
|
"Lmes_1.0",
|
||||||
|
"VersionInfo"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 确保目录存在
|
||||||
|
if (!Directory.Exists(存储路径))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(存储路径);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取最新版本信息
|
||||||
|
[HttpGet("获取最新版本信息")]
|
||||||
|
public ActionResult<VersionInfo> GetLatestVersion()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var files = Directory.GetFiles(存储路径, "*.zip");
|
||||||
|
if (!files.Any())
|
||||||
|
{
|
||||||
|
return NotFound("未找到任何版本文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取最新的版本文件
|
||||||
|
var latestFile = files.OrderByDescending(f => f).First();
|
||||||
|
var fileName = Path.GetFileNameWithoutExtension(latestFile);
|
||||||
|
|
||||||
|
// 计算文件的CRC值
|
||||||
|
string crc;
|
||||||
|
using (var fs = System.IO.File.OpenRead(latestFile))
|
||||||
|
{
|
||||||
|
using var sha = System.Security.Cryptography.SHA256.Create();
|
||||||
|
var hash = sha.ComputeHash(fs);
|
||||||
|
crc = BitConverter.ToString(hash).Replace("-", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VersionInfo
|
||||||
|
{
|
||||||
|
Version = fileName.Split("--")[0],
|
||||||
|
CRC = crc,
|
||||||
|
FileName = Path.GetFileName(latestFile)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, $"获取版本信息失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传新版本
|
||||||
|
[HttpPost("上传新版本")]
|
||||||
|
public async Task<IActionResult> UploadVersion(IFormFile file)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var fileName = file.FileName;
|
||||||
|
var filePath = Path.Combine(存储路径, fileName);
|
||||||
|
|
||||||
|
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||||
|
{
|
||||||
|
await file.CopyToAsync(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证上传的文件是否为有效的ZIP文件
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var archive = ZipFile.OpenRead(filePath))
|
||||||
|
{
|
||||||
|
// 检查是否包含必要的文件
|
||||||
|
if (!archive.Entries.Any(e => e.Name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
System.IO.File.Delete(filePath);
|
||||||
|
return BadRequest("ZIP文件中未找到可执行文件");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
System.IO.File.Delete(filePath);
|
||||||
|
return BadRequest("上传的文件不是有效的ZIP文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok("文件上传成功");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, $"文件上传失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载指定版本
|
||||||
|
[HttpGet("下载指定版本/{fileName}")]
|
||||||
|
public IActionResult DownloadVersion(string fileName)
|
||||||
|
{
|
||||||
|
var filePath = Path.Combine(存储路径, fileName);
|
||||||
|
|
||||||
|
if (!System.IO.File.Exists(filePath))
|
||||||
|
{
|
||||||
|
return NotFound("指定的版本文件不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileStream = System.IO.File.OpenRead(filePath);
|
||||||
|
return File(fileStream, "application/zip", fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
AutoUpdate/AutoUpdateServer/Program.cs
Normal file
53
AutoUpdate/AutoUpdateServer/Program.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
|
|
||||||
|
namespace AutoUpdateServer
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
builder.Services.AddCors(options =>
|
||||||
|
{
|
||||||
|
options.AddPolicy("AllowAll", builder =>
|
||||||
|
{
|
||||||
|
builder.AllowAnyOrigin()
|
||||||
|
.AllowAnyHeader()
|
||||||
|
.AllowAnyMethod();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
builder.Services.AddLogging();
|
||||||
|
builder.Services.Configure<KestrelServerOptions>(options =>
|
||||||
|
{
|
||||||
|
options.Limits.MaxRequestBodySize = 1024 * 1024 * 1024; // 100 MB
|
||||||
|
});
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.UseCors("AllowAll");
|
||||||
|
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
AutoUpdate/AutoUpdateServer/Properties/launchSettings.json
Normal file
25
AutoUpdate/AutoUpdateServer/Properties/launchSettings.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5062",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7116;http://localhost:5062",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
AutoUpdate/AutoUpdateServer/appsettings.Development.json
Normal file
15
AutoUpdate/AutoUpdateServer/appsettings.Development.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Kestrel": {
|
||||||
|
"Endpoints": {
|
||||||
|
"Http": {
|
||||||
|
"Url": "http://*:5000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
AutoUpdate/AutoUpdateServer/appsettings.json
Normal file
9
AutoUpdate/AutoUpdateServer/appsettings.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user