improve:自动更新

This commit is contained in:
2025-07-19 16:03:45 +08:00
parent 1da55f2011
commit 251c7f399e
4 changed files with 175 additions and 83 deletions
+78 -47
View File
@@ -105,12 +105,18 @@ namespace Ink_Canvas.Helpers
return -1;
}
// 检测线路组延迟,返回最快组
// 检测线路组延迟,返回最快组(保持向后兼容)
private static async Task<UpdateLineGroup> GetFastestLineGroup(UpdateChannel channel)
{
var availableGroups = await GetAvailableLineGroupsOrdered(channel);
return availableGroups.Count > 0 ? availableGroups[0] : null;
}
// 获取所有可用线路组,按延迟排序
public static async Task<List<UpdateLineGroup>> GetAvailableLineGroupsOrdered(UpdateChannel channel)
{
var groups = ChannelLineGroups[channel];
long minDelay = long.MaxValue;
UpdateLineGroup bestGroup = null;
var availableGroups = new List<(UpdateLineGroup group, long delay)>();
LogHelper.WriteLogToFile($"AutoUpdate | 开始检测通道 {channel} 下所有线路组延迟...");
@@ -121,11 +127,7 @@ namespace Ink_Canvas.Helpers
if (delay >= 0)
{
LogHelper.WriteLogToFile($"AutoUpdate | 线路组 {group.GroupName} 延迟: {delay}ms");
if (delay < minDelay)
{
minDelay = delay;
bestGroup = group;
}
availableGroups.Add((group, delay));
}
else
{
@@ -133,16 +135,26 @@ namespace Ink_Canvas.Helpers
}
}
if (bestGroup != null)
// 按延迟排序,延迟最小的排在前面
var orderedGroups = availableGroups
.OrderBy(x => x.delay)
.Select(x => x.group)
.ToList();
if (orderedGroups.Count > 0)
{
LogHelper.WriteLogToFile($"AutoUpdate | 选择最快线路组: {bestGroup.GroupName} (延迟: {minDelay}ms)");
LogHelper.WriteLogToFile($"AutoUpdate | 找到 {orderedGroups.Count} 个可用线路组,按延迟排序:");
for (int i = 0; i < orderedGroups.Count; i++)
{
LogHelper.WriteLogToFile($"AutoUpdate | {i + 1}. {orderedGroups[i].GroupName}");
}
}
else
{
LogHelper.WriteLogToFile("AutoUpdate | 所有线路组均不可用", LogHelper.LogType.Error);
}
return bestGroup;
return orderedGroups;
}
// 获取远程版本号
@@ -218,7 +230,7 @@ namespace Ink_Canvas.Helpers
}
}
// 主要的更新检测方法(优先检测延迟)
// 主要的更新检测方法(优先检测延迟,失败时自动切换线路组
public static async Task<(string remoteVersion, UpdateLineGroup lineGroup)> CheckForUpdates(UpdateChannel channel = UpdateChannel.Release, bool alwaysGetRemote = false)
{
try
@@ -227,39 +239,45 @@ namespace Ink_Canvas.Helpers
LogHelper.WriteLogToFile($"AutoUpdate | 本地版本: {localVersion}");
LogHelper.WriteLogToFile($"AutoUpdate | 检测通道 {channel} 下最快线路组...");
// 优先检测延迟,选择最快线路组
var bestGroup = await GetFastestLineGroup(channel);
if (bestGroup == null)
// 获取所有可用线路组(按延迟排序)
var availableGroups = await GetAvailableLineGroupsOrdered(channel);
if (availableGroups.Count == 0)
{
LogHelper.WriteLogToFile("AutoUpdate | 所有线路组均不可用", LogHelper.LogType.Error);
return (null, null);
}
LogHelper.WriteLogToFile($"AutoUpdate | 使用最快线路组获取版本信息: {bestGroup.GroupName}");
string remoteVersion = await GetRemoteVersion(bestGroup.VersionUrl);
if (remoteVersion != null)
// 依次尝试每个线路组,直到成功获取版本信息
foreach (var group in availableGroups)
{
LogHelper.WriteLogToFile($"AutoUpdate | 远程版本: {remoteVersion}");
Version local = new Version(localVersion);
Version remote = new Version(remoteVersion);
LogHelper.WriteLogToFile($"AutoUpdate | 尝试使用线路组获取版本信息: {group.GroupName}");
string remoteVersion = await GetRemoteVersion(group.VersionUrl);
if (remote > local || alwaysGetRemote)
if (remoteVersion != null)
{
LogHelper.WriteLogToFile($"AutoUpdate | 发现新版本或强制获取: {remoteVersion}");
return (remoteVersion, bestGroup);
LogHelper.WriteLogToFile($"AutoUpdate | 成功从线路组 {group.GroupName} 获取远程版本: {remoteVersion}");
Version local = new Version(localVersion);
Version remote = new Version(remoteVersion);
if (remote > local || alwaysGetRemote)
{
LogHelper.WriteLogToFile($"AutoUpdate | 发现新版本或强制获取: {remoteVersion}");
return (remoteVersion, group);
}
else
{
LogHelper.WriteLogToFile($"AutoUpdate | 当前版本已是最新");
return (null, group);
}
}
else
{
LogHelper.WriteLogToFile($"AutoUpdate | 当前版本已是最新");
return (null, bestGroup);
LogHelper.WriteLogToFile($"AutoUpdate | 线路组 {group.GroupName} 获取版本失败,尝试下一个线路组", LogHelper.LogType.Warning);
}
}
else
{
LogHelper.WriteLogToFile("AutoUpdate | 获取远程版本失败", LogHelper.LogType.Error);
return (null, bestGroup);
}
LogHelper.WriteLogToFile("AutoUpdate | 所有线路组均无法获取版本信息", LogHelper.LogType.Error);
return (null, null);
}
catch (Exception ex)
{
@@ -270,6 +288,12 @@ namespace Ink_Canvas.Helpers
// 使用指定线路组下载新版
public static async Task<bool> DownloadSetupFile(string version, UpdateLineGroup group)
{
return await DownloadSetupFileWithFallback(version, new List<UpdateLineGroup> { group });
}
// 使用多线路组下载新版(支持自动切换)
public static async Task<bool> DownloadSetupFileWithFallback(string version, List<UpdateLineGroup> groups)
{
try
{
@@ -288,26 +312,33 @@ namespace Ink_Canvas.Helpers
LogHelper.WriteLogToFile($"AutoUpdate | 创建更新目录: {updatesFolderPath}");
}
string url = string.Format(group.DownloadUrlFormat, version);
string zipFilePath = Path.Combine(updatesFolderPath, $"InkCanvasForClass.CE.{version}.zip");
LogHelper.WriteLogToFile($"AutoUpdate | 从线路组 {group.GroupName} 下载: {url}");
LogHelper.WriteLogToFile($"AutoUpdate | 目标文件路径: {zipFilePath}");
SaveDownloadStatus(false);
bool downloadSuccess = await DownloadFile(url, zipFilePath);
// 依次尝试每个线路组
foreach (var group in groups)
{
string url = string.Format(group.DownloadUrlFormat, version);
LogHelper.WriteLogToFile($"AutoUpdate | 尝试从线路组 {group.GroupName} 下载: {url}");
bool downloadSuccess = await DownloadFile(url, zipFilePath);
if (downloadSuccess)
{
SaveDownloadStatus(true);
LogHelper.WriteLogToFile($"AutoUpdate | 从线路组 {group.GroupName} 下载成功");
return true;
}
else
{
LogHelper.WriteLogToFile($"AutoUpdate | 线路组 {group.GroupName} 下载失败,尝试下一个线路组", LogHelper.LogType.Warning);
}
}
if (downloadSuccess)
{
SaveDownloadStatus(true);
LogHelper.WriteLogToFile("AutoUpdate | 安装包下载成功");
return true;
}
else
{
LogHelper.WriteLogToFile("AutoUpdate | 下载失败", LogHelper.LogType.Error);
return false;
}
LogHelper.WriteLogToFile("AutoUpdate | 所有线路组下载均失败", LogHelper.LogType.Error);
return false;
}
catch (Exception ex)
{
+41 -27
View File
@@ -425,7 +425,42 @@ namespace Ink_Canvas {
}
}
// 辅助方法:使用多线路组下载更新
private async Task<bool> DownloadUpdateWithFallback(string version, AutoUpdateHelper.UpdateLineGroup primaryGroup, UpdateChannel channel)
{
try
{
// 如果主要线路组可用,直接使用
if (primaryGroup != null)
{
LogHelper.WriteLogToFile($"AutoUpdate | 使用主要线路组下载: {primaryGroup.GroupName}");
return await AutoUpdateHelper.DownloadSetupFile(version, primaryGroup);
}
// 如果主要线路组不可用,获取所有可用线路组
LogHelper.WriteLogToFile("AutoUpdate | 主要线路组不可用,获取所有可用线路组");
var availableGroups = await AutoUpdateHelper.GetAvailableLineGroupsOrdered(channel);
if (availableGroups.Count == 0)
{
LogHelper.WriteLogToFile("AutoUpdate | 没有可用的线路组", LogHelper.LogType.Error);
return false;
}
LogHelper.WriteLogToFile($"AutoUpdate | 使用 {availableGroups.Count} 个可用线路组进行下载");
return await AutoUpdateHelper.DownloadSetupFileWithFallback(version, availableGroups);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | 下载更新时出错: {ex.Message}", LogHelper.LogType.Error);
return false;
}
}
private async void AutoUpdate() {
// 清除之前的更新状态,确保使用新通道重新检查
AvailableLatestVersion = null;
AvailableLatestLineGroup = null;
// 使用当前选择的更新通道检查更新
var (remoteVersion, lineGroup) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel);
AvailableLatestVersion = remoteVersion;
@@ -461,15 +496,8 @@ namespace Ink_Canvas {
if (Settings.Startup.IsAutoUpdateWithSilence) {
LogHelper.WriteLogToFile("AutoUpdate | Silent update enabled, downloading update automatically without notification");
// 静默下载更新,传递当前选择的更新通道
if (AvailableLatestLineGroup != null)
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, AvailableLatestLineGroup);
else
{
var (_, lineGroup2) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel, true);
if (lineGroup2 != null)
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, lineGroup2);
}
// 静默下载更新,使用多线路组下载功能
isDownloadSuccessful = await DownloadUpdateWithFallback(AvailableLatestVersion, AvailableLatestLineGroup, Settings.Startup.UpdateChannel);
if (isDownloadSuccessful) {
LogHelper.WriteLogToFile("AutoUpdate | Update downloaded successfully, will install when conditions are met");
@@ -518,15 +546,8 @@ namespace Ink_Canvas {
// 显示下载进度提示
MessageBox.Show("开始下载更新,请稍候...", "正在更新", MessageBoxButton.OK, MessageBoxImage.Information);
// 下载更新文件,传递当前选择的更新通道
if (AvailableLatestLineGroup != null)
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, AvailableLatestLineGroup);
else
{
var (_, lineGroup2) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel, true);
if (lineGroup2 != null)
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, lineGroup2);
}
// 下载更新文件,使用多线路组下载功能
isDownloadSuccessful = await DownloadUpdateWithFallback(AvailableLatestVersion, AvailableLatestLineGroup, Settings.Startup.UpdateChannel);
if (isDownloadSuccessful) {
// 下载成功,提示用户准备安装
@@ -555,15 +576,8 @@ namespace Ink_Canvas {
// 稍后更新:静默下载,在软件关闭时自动安装
LogHelper.WriteLogToFile("AutoUpdate | User chose to update later");
// 不管设置如何,都进行下载
if (AvailableLatestLineGroup != null)
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, AvailableLatestLineGroup);
else
{
var (_, lineGroup2) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel, true);
if (lineGroup2 != null)
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, lineGroup2);
}
// 不管设置如何,都进行下载,使用多线路组下载功能
isDownloadSuccessful = await DownloadUpdateWithFallback(AvailableLatestVersion, AvailableLatestLineGroup, Settings.Startup.UpdateChannel);
if (isDownloadSuccessful) {
LogHelper.WriteLogToFile("AutoUpdate | Update downloaded successfully, will install when application closes");
+30 -2
View File
@@ -1992,14 +1992,42 @@ namespace Ink_Canvas {
HideSubPanels();
}
private void UpdateChannelSelector_Checked(object sender, RoutedEventArgs e) {
private async void UpdateChannelSelector_Checked(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
var radioButton = sender as System.Windows.Controls.RadioButton;
if (radioButton != null) {
string channel = radioButton.Tag.ToString();
Settings.Startup.UpdateChannel = channel == "Beta" ? UpdateChannel.Beta : UpdateChannel.Release;
UpdateChannel newChannel = channel == "Beta" ? UpdateChannel.Beta : UpdateChannel.Release;
// 如果通道没有变化,不需要执行更新检查
if (Settings.Startup.UpdateChannel == newChannel) {
return;
}
Settings.Startup.UpdateChannel = newChannel;
LogHelper.WriteLogToFile($"Settings | Update channel changed to {Settings.Startup.UpdateChannel}");
SaveSettingsToFile();
// 如果启用了自动更新,立即执行完整的检查更新操作
if (Settings.Startup.IsAutoUpdate) {
LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, performing immediate update check");
// 执行完整的更新检查
await Task.Run(async () => {
try {
// 调用主窗口的AutoUpdate方法,它会自动清除之前的更新状态并使用新通道重新检查
Dispatcher.Invoke(() => {
AutoUpdate();
});
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"AutoUpdate | Error during channel switch update check: {ex.Message}", LogHelper.LogType.Error);
}
});
}
else {
LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, but auto-update is disabled");
}
}
}
+26 -7
View File
@@ -329,17 +329,36 @@ namespace Ink_Canvas {
if (!File.Exists(statusFilePath) || File.ReadAllText(statusFilePath).Trim().ToLower() != "true") {
LogHelper.WriteLogToFile("AutoUpdate | Update file not downloaded yet");
// 尝试下载更新文件
// 尝试下载更新文件,使用多线路组下载功能
Task.Run(async () => {
bool isDownloadSuccessful = false;
if (AvailableLatestLineGroup != null)
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, AvailableLatestLineGroup);
else
try
{
var (_, lineGroup2) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel, true);
if (lineGroup2 != null)
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, lineGroup2);
// 如果主要线路组可用,直接使用
if (AvailableLatestLineGroup != null)
{
LogHelper.WriteLogToFile($"AutoUpdate | 使用主要线路组下载: {AvailableLatestLineGroup.GroupName}");
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, AvailableLatestLineGroup);
}
// 如果主要线路组不可用或下载失败,获取所有可用线路组
if (!isDownloadSuccessful)
{
LogHelper.WriteLogToFile("AutoUpdate | 主要线路组不可用或下载失败,获取所有可用线路组");
var availableGroups = await AutoUpdateHelper.GetAvailableLineGroupsOrdered(Settings.Startup.UpdateChannel);
if (availableGroups.Count > 0)
{
LogHelper.WriteLogToFile($"AutoUpdate | 使用 {availableGroups.Count} 个可用线路组进行下载");
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFileWithFallback(AvailableLatestVersion, availableGroups);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | 下载更新时出错: {ex.Message}", LogHelper.LogType.Error);
}
if (isDownloadSuccessful) {
LogHelper.WriteLogToFile("AutoUpdate | Update downloaded successfully, will check again for installation");
// 重新启动计时器,下次检查时安装