Skip to content

Commit 7db87b7

Browse files
authored
Merge pull request #61 from InkCanvasForClass/beta
ICC CE 1.7.0.0 (ICC CE Beta1.7.0.0)
2 parents 8fada62 + 54d0aac commit 7db87b7

9 files changed

Lines changed: 398 additions & 126 deletions

File tree

Ink Canvas/Helpers/AutoUpdateHelper.cs

Lines changed: 188 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,35 @@ namespace Ink_Canvas.Helpers
1515
{
1616
internal class AutoUpdateHelper
1717
{
18-
public static async Task<string> CheckForUpdates(string proxy = null)
18+
// 定义超时时间为10秒
19+
private static readonly TimeSpan RequestTimeout = TimeSpan.FromSeconds(10);
20+
21+
public static async Task<string> CheckForUpdates(string proxy = null, UpdateChannel channel = UpdateChannel.Release)
1922
{
2023
try
2124
{
2225
string localVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
2326
LogHelper.WriteLogToFile($"AutoUpdate | Local version: {localVersion}");
2427

2528
string remoteAddress = proxy;
26-
string primaryUrl = "https://raw.githubusercontent.com/InkCanvasForClass/community/refs/heads/main/AutomaticUpdateVersionControl.txt";
27-
string fallbackUrl = "https://raw.bgithub.xyz/InkCanvasForClass/community/refs/heads/main/AutomaticUpdateVersionControl.txt";
29+
30+
// 根据通道选择URL
31+
string primaryUrl, fallbackUrl;
32+
33+
if (channel == UpdateChannel.Release)
34+
{
35+
// Release通道版本信息地址
36+
primaryUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/AutomaticUpdateVersionControl.txt";
37+
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
38+
}
39+
else
40+
{
41+
// Beta通道版本信息地址
42+
primaryUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
43+
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
44+
}
45+
46+
LogHelper.WriteLogToFile($"AutoUpdate | Checking for updates on {channel} channel");
2847

2948
// 先尝试主地址
3049
remoteAddress += primaryUrl;
@@ -72,19 +91,19 @@ public static async Task<string> GetRemoteVersion(string fileUrl)
7291
{
7392
try
7493
{
75-
// Set a reasonable timeout
76-
client.Timeout = TimeSpan.FromSeconds(10); // 减少超时时间以便更快切换到备用地址
94+
// 设置超时时间为10秒
95+
client.Timeout = RequestTimeout;
7796

7897
LogHelper.WriteLogToFile($"AutoUpdate | Sending HTTP request to: {fileUrl}");
7998

8099
// 使用带超时的Task.WhenAny来确保请求不会无限期等待
81100
var downloadTask = client.GetAsync(fileUrl);
82-
var timeoutTask = Task.Delay(client.Timeout);
101+
var timeoutTask = Task.Delay(RequestTimeout);
83102

84103
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
85104
if (completedTask == timeoutTask)
86105
{
87-
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out after {client.Timeout.TotalSeconds} seconds", LogHelper.LogType.Error);
106+
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out after {RequestTimeout.TotalSeconds} seconds", LogHelper.LogType.Error);
88107
return null;
89108
}
90109

@@ -150,7 +169,7 @@ public static async Task<string> GetRemoteVersion(string fileUrl)
150169
private static string updatesFolderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AutoUpdate");
151170
private static string statusFilePath = null;
152171

153-
public static async Task<bool> DownloadSetupFileAndSaveStatus(string version, string proxy = "")
172+
public static async Task<bool> DownloadSetupFileAndSaveStatus(string version, string proxy = "", UpdateChannel channel = UpdateChannel.Release)
154173
{
155174
try
156175
{
@@ -169,10 +188,21 @@ public static async Task<bool> DownloadSetupFileAndSaveStatus(string version, st
169188
LogHelper.WriteLogToFile($"AutoUpdate | Created updates directory: {updatesFolderPath}");
170189
}
171190

172-
// 主下载地址
173-
string primaryUrl = $"{proxy}https://github.com/InkCanvasForClass/community/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
174-
// 备用下载地址
175-
string fallbackUrl = $"{proxy}https://bgithub.xyz/InkCanvasForClass/community/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
191+
// 根据通道选择下载地址
192+
string primaryUrl, fallbackUrl;
193+
194+
if (channel == UpdateChannel.Release)
195+
{
196+
// Release通道下载地址
197+
primaryUrl = $"{proxy}https://github.com/InkCanvasForClass/community/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
198+
fallbackUrl = $"{proxy}https://bgithub.xyz/InkCanvasForClass/community/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
199+
}
200+
else
201+
{
202+
// Beta通道下载地址
203+
primaryUrl = $"{proxy}https://github.com/InkCanvasForClass/community-beta/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
204+
fallbackUrl = $"{proxy}https://bgithub.xyz/InkCanvasForClass/community-beta/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
205+
}
176206

177207
LogHelper.WriteLogToFile($"AutoUpdate | Primary download URL: {primaryUrl}");
178208

@@ -222,7 +252,7 @@ private static async Task<bool> DownloadFile(string fileUrl, string destinationP
222252
try
223253
{
224254
// Configure client
225-
client.Timeout = TimeSpan.FromMinutes(5); // Longer timeout for downloading larger files
255+
client.Timeout = TimeSpan.FromMinutes(5); // 下载文件需要更长的超时时间
226256
client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater");
227257

228258
LogHelper.WriteLogToFile($"AutoUpdate | Downloading from: {fileUrl}");
@@ -239,7 +269,7 @@ private static async Task<bool> DownloadFile(string fileUrl, string destinationP
239269

240270
// 使用带超时的Task.WhenAny来确保请求不会无限期等待
241271
var downloadTask = client.GetAsync(fileUrl, HttpCompletionOption.ResponseHeadersRead);
242-
var initialTimeoutTask = Task.Delay(TimeSpan.FromSeconds(30)); // 30秒内必须有响应
272+
var initialTimeoutTask = Task.Delay(RequestTimeout); // 使用全局定义的10秒超时
243273

244274
var completedTask = await Task.WhenAny(downloadTask, initialTimeoutTask);
245275
if (completedTask == initialTimeoutTask)
@@ -769,6 +799,150 @@ public static void DeleteUpdatesFolder()
769799
LogHelper.WriteLogToFile($"AutoUpdate | Error deleting updates folder: {ex.Message}", LogHelper.LogType.Error);
770800
}
771801
}
802+
803+
// 新增:版本修复方法,强制下载并安装指定通道的最新版本
804+
public static async Task<bool> FixVersion(UpdateChannel channel = UpdateChannel.Release)
805+
{
806+
try
807+
{
808+
LogHelper.WriteLogToFile($"AutoUpdate | Starting version fix for {channel} channel");
809+
810+
// 获取当前通道的最新版本
811+
string latestVersion = await CheckForUpdates(null, channel);
812+
813+
if (string.IsNullOrEmpty(latestVersion))
814+
{
815+
LogHelper.WriteLogToFile("AutoUpdate | No newer version found for fixing", LogHelper.LogType.Warning);
816+
return false;
817+
}
818+
819+
// 下载最新版本
820+
bool downloadResult = await DownloadSetupFileAndSaveStatus(latestVersion, "", channel);
821+
822+
if (!downloadResult)
823+
{
824+
LogHelper.WriteLogToFile("AutoUpdate | Failed to download update for fixing", LogHelper.LogType.Error);
825+
return false;
826+
}
827+
828+
// 执行安装,非静默模式
829+
InstallNewVersionApp(latestVersion, false);
830+
831+
// 设置为用户主动退出,避免被看门狗判定为崩溃
832+
App.IsAppExitByUser = true;
833+
834+
// 关闭应用程序
835+
Application.Current.Dispatcher.Invoke(() => {
836+
Application.Current.Shutdown();
837+
});
838+
839+
return true;
840+
}
841+
catch (Exception ex)
842+
{
843+
LogHelper.WriteLogToFile($"AutoUpdate | Error in FixVersion: {ex.Message}", LogHelper.LogType.Error);
844+
return false;
845+
}
846+
}
847+
848+
// 获取更新日志
849+
public static async Task<string> GetUpdateLog(UpdateChannel channel = UpdateChannel.Release)
850+
{
851+
try
852+
{
853+
string primaryUrl, fallbackUrl;
854+
855+
if (channel == UpdateChannel.Release)
856+
{
857+
// Release通道更新日志地址
858+
primaryUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/UpdateLog.txt";
859+
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/UpdateLog.txt";
860+
}
861+
else
862+
{
863+
// Beta通道更新日志地址
864+
primaryUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/UpdateLog.txt";
865+
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/UpdateLog.txt";
866+
}
867+
868+
LogHelper.WriteLogToFile($"AutoUpdate | Getting update log from {channel} channel");
869+
870+
// 先尝试主地址
871+
string updateLog = await GetRemoteContent(primaryUrl);
872+
873+
// 如果主地址失败,尝试备用地址
874+
if (string.IsNullOrEmpty(updateLog))
875+
{
876+
LogHelper.WriteLogToFile($"AutoUpdate | Primary URL failed for update log, trying fallback URL");
877+
updateLog = await GetRemoteContent(fallbackUrl);
878+
}
879+
880+
if (!string.IsNullOrEmpty(updateLog))
881+
{
882+
LogHelper.WriteLogToFile($"AutoUpdate | Successfully retrieved update log");
883+
return updateLog;
884+
}
885+
else
886+
{
887+
LogHelper.WriteLogToFile("AutoUpdate | Failed to retrieve update log from both URLs.", LogHelper.LogType.Error);
888+
return $"# 无法获取更新日志\n\n无法从服务器获取更新日志信息,请检查网络连接后重试。";
889+
}
890+
}
891+
catch (Exception ex)
892+
{
893+
LogHelper.WriteLogToFile($"AutoUpdate | Error in GetUpdateLog: {ex.Message}", LogHelper.LogType.Error);
894+
return $"# 获取更新日志时发生错误\n\n错误信息: {ex.Message}";
895+
}
896+
}
897+
898+
// 获取远程内容的通用方法
899+
private static async Task<string> GetRemoteContent(string fileUrl)
900+
{
901+
using (HttpClient client = new HttpClient())
902+
{
903+
try
904+
{
905+
// 设置超时时间为10秒
906+
client.Timeout = RequestTimeout;
907+
908+
LogHelper.WriteLogToFile($"AutoUpdate | Sending HTTP request to: {fileUrl}");
909+
910+
// 使用带超时的Task.WhenAny来确保请求不会无限期等待
911+
var downloadTask = client.GetAsync(fileUrl);
912+
var timeoutTask = Task.Delay(RequestTimeout);
913+
914+
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
915+
if (completedTask == timeoutTask)
916+
{
917+
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out after {RequestTimeout.TotalSeconds} seconds", LogHelper.LogType.Error);
918+
return null;
919+
}
920+
921+
// 请求完成,检查结果
922+
HttpResponseMessage response = await downloadTask;
923+
924+
LogHelper.WriteLogToFile($"AutoUpdate | HTTP response status: {response.StatusCode}");
925+
response.EnsureSuccessStatusCode();
926+
927+
string content = await response.Content.ReadAsStringAsync();
928+
return content;
929+
}
930+
catch (HttpRequestException ex)
931+
{
932+
LogHelper.WriteLogToFile($"AutoUpdate | HTTP request error: {ex.Message}", LogHelper.LogType.Error);
933+
}
934+
catch (TaskCanceledException ex)
935+
{
936+
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out: {ex.Message}", LogHelper.LogType.Error);
937+
}
938+
catch (Exception ex)
939+
{
940+
LogHelper.WriteLogToFile($"AutoUpdate | Error: {ex.Message}", LogHelper.LogType.Error);
941+
}
942+
943+
return null;
944+
}
945+
}
772946
}
773947

774948
internal class AutoUpdateWithSilenceTimeComboBox

Ink Canvas/MainWindow.xaml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,16 +652,36 @@
652652
FontSize="26" />
653653
</GroupBox.Header>
654654
<ui:SimpleStackPanel Spacing="6">
655-
<ui:ToggleSwitch OnContent="" OffContent="" Visibility="Collapsed"
655+
<ui:ToggleSwitch OnContent="" OffContent=""
656656
Name="ToggleSwitchIsAutoUpdate" Header="自动检查更新"
657657
FontFamily="Microsoft YaHei UI"
658658
Toggled="ToggleSwitchIsAutoUpdate_Toggled" />
659-
<ui:ToggleSwitch OnContent="" OffContent="" Visibility="Collapsed"
659+
<ui:ToggleSwitch OnContent="" OffContent=""
660660
Name="ToggleSwitchIsAutoUpdateWithSilence" Header="静默更新"
661661
FontFamily="Microsoft YaHei UI"
662662
Toggled="ToggleSwitchIsAutoUpdateWithSilence_Toggled" />
663+
<TextBlock Text="# 静默更新将在软件不使用时自动安装,无需手动操作" TextWrapping="Wrap" Foreground="#a1a1aa" />
664+
665+
<!-- 更新通道选择 -->
666+
<ui:SimpleStackPanel Spacing="8" Margin="0,8,0,0">
667+
<TextBlock Text="更新通道" FontSize="15" FontWeight="Bold" Foreground="#fafafa"/>
668+
<ui:RadioButtons x:Name="UpdateChannelSelector" Margin="0,4,0,0">
669+
<RadioButton Content="稳定版 (Release)" GroupName="UpdateChannel"
670+
Tag="Release" Checked="UpdateChannelSelector_Checked"/>
671+
<RadioButton Content="测试版 (Beta)" GroupName="UpdateChannel"
672+
Tag="Beta" Checked="UpdateChannelSelector_Checked"/>
673+
</ui:RadioButtons>
674+
<TextBlock Text="# 稳定版提供可靠更新,测试版提供新功能抢先体验" TextWrapping="Wrap" Foreground="#a1a1aa" />
675+
</ui:SimpleStackPanel>
676+
677+
<!-- 版本修复按钮 -->
678+
<Button x:Name="FixVersionButton" Content="版本修复" Margin="0,8,0,0"
679+
Width="120" HorizontalAlignment="Left" Click="FixVersionButton_Click"/>
680+
<TextBlock Text="# 版本修复会根据当前选择的通道下载最新版本并执行安装,可用于修复损坏的安装"
681+
TextWrapping="Wrap" Foreground="#a1a1aa" />
682+
663683
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Padding="12"
664-
Visibility="{Binding ElementName=ToggleSwitchIsAutoUpdateWithSilence, Path=Visibility}">
684+
Visibility="{Binding ElementName=ToggleSwitchIsAutoUpdateWithSilence, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
665685
<ui:SimpleStackPanel Spacing="12">
666686
<TextBlock
667687
Text="# 关闭静默更新后,已完成安装包的下载后将会弹窗询问是否进行更新,开启静默更新后将会在安装包下载完成后每隔十分钟进行如下检测:①处于静默更新时间段内 ②未处于书写模式 ③未处于画板内。若以上检测通过即会关闭软件进行自动更新。"

0 commit comments

Comments
 (0)