improve:自动更新
This commit is contained in:
@@ -11,6 +11,7 @@ using System.Windows.Controls;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Ink_Canvas.Helpers
|
||||
{
|
||||
@@ -342,44 +343,92 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
// 通过GitHub API获取最新Release信息
|
||||
private static async Task<(string version, string downloadUrl, string releaseNotes)> GetLatestGithubRelease(UpdateChannel channel)
|
||||
{
|
||||
try
|
||||
{
|
||||
string apiUrl = channel == UpdateChannel.Beta
|
||||
? "https://api.github.com/repos/InkCanvasForClass/community-beta/releases/latest"
|
||||
: "https://api.github.com/repos/InkCanvasForClass/community/releases/latest";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater");
|
||||
var response = await client.GetStringAsync(apiUrl);
|
||||
var json = JObject.Parse(response);
|
||||
string version = json["tag_name"]?.ToString();
|
||||
string releaseNotes = json["body"]?.ToString();
|
||||
string downloadUrl = json["assets"]?.First?["browser_download_url"]?.ToString();
|
||||
if (!string.IsNullOrEmpty(version) && !string.IsNullOrEmpty(downloadUrl))
|
||||
return (version, downloadUrl, releaseNotes);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | GitHub Releases API 获取失败: {ex.Message}", LogHelper.LogType.Warning);
|
||||
}
|
||||
return (null, null, null);
|
||||
}
|
||||
|
||||
// 主要的更新检测方法(优先检测延迟,失败时自动切换线路组)
|
||||
public static async Task<(string remoteVersion, UpdateLineGroup lineGroup)> CheckForUpdates(UpdateChannel channel = UpdateChannel.Release, bool alwaysGetRemote = false)
|
||||
public static async Task<(string remoteVersion, UpdateLineGroup lineGroup, string releaseNotes, string directDownloadUrl)> CheckForUpdates(UpdateChannel channel = UpdateChannel.Release, bool alwaysGetRemote = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
string localVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 本地版本: {localVersion}");
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 检测通道 {channel} 下最快线路组...");
|
||||
|
||||
// 获取所有可用线路组(按延迟排序)
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 优先通过GitHub Releases API检测...");
|
||||
// 1. 优先通过GitHub Releases API获取
|
||||
var (apiVersion, apiDownloadUrl, apiReleaseNotes) = await GetLatestGithubRelease(channel);
|
||||
if (!string.IsNullOrEmpty(apiVersion) && !string.IsNullOrEmpty(apiDownloadUrl))
|
||||
{
|
||||
Version local = new Version(localVersion);
|
||||
Version remote = new Version(apiVersion.TrimStart('v', 'V'));
|
||||
if (remote > local || alwaysGetRemote)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 通过GitHub Releases API发现新版本: {apiVersion}");
|
||||
// 用一个虚拟的UpdateLineGroup表示API直链
|
||||
var apiGroup = new UpdateLineGroup
|
||||
{
|
||||
GroupName = "GitHub Releases API",
|
||||
VersionUrl = "",
|
||||
DownloadUrlFormat = apiDownloadUrl,
|
||||
LogUrl = ""
|
||||
};
|
||||
return (apiVersion, apiGroup, apiReleaseNotes, apiDownloadUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 当前版本已是最新 (GitHub Releases API)");
|
||||
return (null, null, apiReleaseNotes, null);
|
||||
}
|
||||
}
|
||||
// 2. 回退到原有txt方案
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | GitHub Releases API获取失败,回退到txt方案...");
|
||||
var availableGroups = await GetAvailableLineGroupsOrdered(channel);
|
||||
if (availableGroups.Count == 0)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 所有线路组均不可用", LogHelper.LogType.Error);
|
||||
return (null, null);
|
||||
return (null, null, null, null);
|
||||
}
|
||||
|
||||
// 依次尝试每个线路组,直到成功获取版本信息
|
||||
foreach (var group in availableGroups)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 尝试使用线路组获取版本信息: {group.GroupName}");
|
||||
string remoteVersion = await GetRemoteVersion(group.VersionUrl);
|
||||
|
||||
if (remoteVersion != null)
|
||||
{
|
||||
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);
|
||||
return (remoteVersion, group, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 当前版本已是最新");
|
||||
return (null, group);
|
||||
return (null, group, null, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -387,14 +436,13 @@ namespace Ink_Canvas.Helpers
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 线路组 {group.GroupName} 获取版本失败,尝试下一个线路组", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 所有线路组均无法获取版本信息", LogHelper.LogType.Error);
|
||||
return (null, null);
|
||||
return (null, null, null, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | CheckForUpdates错误: {ex.Message}", LogHelper.LogType.Error);
|
||||
return (null, null);
|
||||
return (null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1065,7 +1113,7 @@ namespace Ink_Canvas.Helpers
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 开始修复版本,通道: {channel}");
|
||||
|
||||
// 获取远程版本号(自动选择最快线路组,始终下载远程版本)
|
||||
var (remoteVersion, group) = await CheckForUpdates(channel, true);
|
||||
var (remoteVersion, group, _, _) = await CheckForUpdates(channel, true);
|
||||
if (string.IsNullOrEmpty(remoteVersion) || group == null)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 修复版本时获取远程版本失败", LogHelper.LogType.Error);
|
||||
@@ -1097,6 +1145,37 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有GitHub历史版本(Release)
|
||||
public static async Task<List<(string version, string downloadUrl, string releaseNotes)>> GetAllGithubReleases(UpdateChannel channel = UpdateChannel.Release)
|
||||
{
|
||||
var result = new List<(string, string, string)>();
|
||||
try
|
||||
{
|
||||
string apiUrl = channel == UpdateChannel.Beta
|
||||
? "https://api.github.com/repos/InkCanvasForClass/community-beta/releases"
|
||||
: "https://api.github.com/repos/InkCanvasForClass/community/releases";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater");
|
||||
var response = await client.GetStringAsync(apiUrl);
|
||||
var arr = JArray.Parse(response);
|
||||
foreach (var item in arr)
|
||||
{
|
||||
string version = item["tag_name"]?.ToString();
|
||||
string releaseNotes = item["body"]?.ToString();
|
||||
string downloadUrl = item["assets"]?.First?["browser_download_url"]?.ToString();
|
||||
if (!string.IsNullOrEmpty(version) && !string.IsNullOrEmpty(downloadUrl))
|
||||
result.Add((version, downloadUrl, releaseNotes));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 获取历史版本失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 测试Windows 7 TLS连接的方法
|
||||
public static async Task<bool> TestWindows7TlsConnection()
|
||||
{
|
||||
|
||||
@@ -552,7 +552,7 @@ namespace Ink_Canvas {
|
||||
AvailableLatestLineGroup = null;
|
||||
|
||||
// 使用当前选择的更新通道检查更新
|
||||
var (remoteVersion, lineGroup) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel);
|
||||
var (remoteVersion, lineGroup, apiReleaseNotes, directDownloadUrl) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel);
|
||||
AvailableLatestVersion = remoteVersion;
|
||||
AvailableLatestLineGroup = lineGroup;
|
||||
|
||||
|
||||
@@ -78,6 +78,12 @@
|
||||
Background="#f8fafc" BorderBrush="#cbd5e1" ToolTip="跳过此版本更新" Visibility="Visible" IsEnabled="True"/>
|
||||
</ui:SimpleStackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 下载进度条和状态 -->
|
||||
<StackPanel x:Name="DownloadProgressPanel" Orientation="Vertical" HorizontalAlignment="Center" Margin="0,10,0,0" Visibility="Collapsed">
|
||||
<ProgressBar x:Name="DownloadProgressBar" Width="360" Height="18" Minimum="0" Maximum="100" Value="0"/>
|
||||
<TextBlock x:Name="DownloadProgressText" Text="正在下载..." FontSize="14" Foreground="#2563eb" HorizontalAlignment="Center" Margin="0,6,0,0"/>
|
||||
</StackPanel>
|
||||
</ui:SimpleStackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -7,6 +7,8 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
|
||||
namespace Ink_Canvas
|
||||
{
|
||||
@@ -129,16 +131,46 @@ namespace Ink_Canvas
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Update dialog buttons visibility ensured");
|
||||
}
|
||||
|
||||
private void UpdateNowButton_Click(object sender, RoutedEventArgs e)
|
||||
private async void UpdateNowButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Update Now button clicked");
|
||||
|
||||
// 设置结果为立即更新
|
||||
Result = UpdateResult.UpdateNow;
|
||||
|
||||
// 关闭窗口,返回到MainWindow处理后续下载和安装流程
|
||||
DialogResult = true;
|
||||
Close();
|
||||
// 禁用按钮,显示进度条
|
||||
UpdateNowButton.IsEnabled = false;
|
||||
UpdateLaterButton.IsEnabled = false;
|
||||
SkipVersionButton.IsEnabled = false;
|
||||
DownloadProgressPanel.Visibility = Visibility.Visible;
|
||||
DownloadProgressBar.Value = 0;
|
||||
DownloadProgressText.Text = "正在准备下载...";
|
||||
|
||||
// 启动下载
|
||||
bool downloadSuccess = false;
|
||||
try
|
||||
{
|
||||
downloadSuccess = await DownloadUpdateAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DownloadProgressText.Text = $"下载失败: {ex.Message}";
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 下载异常: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
|
||||
if (downloadSuccess)
|
||||
{
|
||||
DownloadProgressBar.Value = 100;
|
||||
DownloadProgressText.Text = "下载完成,准备安装...";
|
||||
await Task.Delay(800);
|
||||
// 设置结果为立即更新
|
||||
Result = UpdateResult.UpdateNow;
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
DownloadProgressText.Text = "下载失败,请检查网络后重试。";
|
||||
UpdateNowButton.IsEnabled = true;
|
||||
UpdateLaterButton.IsEnabled = true;
|
||||
SkipVersionButton.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLaterButton_Click(object sender, RoutedEventArgs e)
|
||||
@@ -279,5 +311,84 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 下载更新并实时更新进度条(支持断点续传)
|
||||
private async Task<bool> DownloadUpdateAsync()
|
||||
{
|
||||
string version = NewVersion;
|
||||
string updatesFolderPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "AutoUpdate");
|
||||
if (!Directory.Exists(updatesFolderPath))
|
||||
Directory.CreateDirectory(updatesFolderPath);
|
||||
string zipFilePath = Path.Combine(updatesFolderPath, $"InkCanvasForClass.CE.{version}.zip");
|
||||
string tmpFilePath = zipFilePath + ".tmp";
|
||||
|
||||
// 获取下载链接(此处假设主程序已将下载直链传入,或可通过AutoUpdateHelper获取)
|
||||
string downloadUrl = null;
|
||||
if (App.Current.Properties.Contains("UpdateDirectDownloadUrl"))
|
||||
downloadUrl = App.Current.Properties["UpdateDirectDownloadUrl"] as string;
|
||||
if (string.IsNullOrEmpty(downloadUrl))
|
||||
{
|
||||
// 兜底:用GitHub主线格式
|
||||
downloadUrl = $"https://github.com/InkCanvasForClass/community/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
|
||||
}
|
||||
|
||||
long existingLength = 0;
|
||||
if (File.Exists(tmpFilePath))
|
||||
existingLength = new FileInfo(tmpFilePath).Length;
|
||||
|
||||
try
|
||||
{
|
||||
using (var client = new System.Net.Http.HttpClient())
|
||||
{
|
||||
client.Timeout = System.TimeSpan.FromMinutes(10);
|
||||
client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater");
|
||||
if (existingLength > 0)
|
||||
client.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(existingLength, null);
|
||||
|
||||
using (var response = await client.GetAsync(downloadUrl, System.Net.Http.HttpCompletionOption.ResponseHeadersRead))
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
var totalBytes = response.Content.Headers.ContentLength.HasValue
|
||||
? response.Content.Headers.ContentLength.Value + existingLength
|
||||
: -1L;
|
||||
|
||||
using (var stream = await response.Content.ReadAsStreamAsync())
|
||||
using (var fs = new FileStream(tmpFilePath, FileMode.Append, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
byte[] buffer = new byte[8192];
|
||||
long totalRead = existingLength;
|
||||
int read;
|
||||
var lastUpdate = DateTime.Now;
|
||||
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
await fs.WriteAsync(buffer, 0, read);
|
||||
totalRead += read;
|
||||
if ((DateTime.Now - lastUpdate).TotalMilliseconds > 200)
|
||||
{
|
||||
int percent = totalBytes > 0 ? (int)(totalRead * 100 / totalBytes) : 0;
|
||||
DownloadProgressBar.Value = percent;
|
||||
DownloadProgressText.Text = totalBytes > 0
|
||||
? $"已下载 {totalRead / 1024 / 1024.0:F2} MB / {totalBytes / 1024 / 1024.0:F2} MB ({percent}%)"
|
||||
: $"已下载 {totalRead / 1024 / 1024.0:F2} MB";
|
||||
lastUpdate = DateTime.Now;
|
||||
}
|
||||
}
|
||||
DownloadProgressBar.Value = 100;
|
||||
DownloadProgressText.Text = "下载完成,正在校验...";
|
||||
await fs.FlushAsync();
|
||||
}
|
||||
if (File.Exists(zipFilePath)) File.Delete(zipFilePath);
|
||||
File.Move(tmpFilePath, zipFilePath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | 断点续传下载失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
// 不删除 .tmp 文件,便于下次断点续传
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<Window x:Class="Ink_Canvas.HistoryRollbackWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
|
||||
xmlns:mdxam="clr-namespace:MdXaml;assembly=MdXaml"
|
||||
mc:Ignorable="d"
|
||||
Title="历史版本回滚" Height="600" Width="850" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
|
||||
<Grid Background="#fafafa">
|
||||
<ui:SimpleStackPanel VerticalAlignment="Stretch" Spacing="0">
|
||||
<TextBlock Text="选择历史版本进行回滚" FontSize="24" FontWeight="Bold" Foreground="#2563eb" Margin="24,24,0,12"/>
|
||||
<ComboBox x:Name="VersionComboBox" Width="400" Height="36" Margin="24,0,0,0" DisplayMemberPath="Version" SelectionChanged="VersionComboBox_SelectionChanged"/>
|
||||
<Border BorderBrush="#3f3f46" Background="White" BorderThickness="1" CornerRadius="4" Margin="24,16,24,0" Height="180">
|
||||
<mdxam:MarkdownScrollViewer x:Name="ReleaseNotesViewer" Foreground="Black" MarkdownStyleName="GithubLike"/>
|
||||
</Border>
|
||||
<Button x:Name="RollbackButton" Content="回滚到此版本" Width="360" Height="48" Margin="24,24,0,0" Click="RollbackButton_Click"/>
|
||||
<StackPanel x:Name="DownloadProgressPanel" Orientation="Vertical" HorizontalAlignment="Center" Margin="0,10,0,0" Visibility="Collapsed">
|
||||
<ProgressBar x:Name="DownloadProgressBar" Width="360" Height="18" Minimum="0" Maximum="100" Value="0"/>
|
||||
<TextBlock x:Name="DownloadProgressText" Text="正在下载..." FontSize="14" Foreground="#2563eb" HorizontalAlignment="Center" Margin="0,6,0,0"/>
|
||||
</StackPanel>
|
||||
</ui:SimpleStackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,165 @@
|
||||
using Ink_Canvas.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Ink_Canvas
|
||||
{
|
||||
public partial class HistoryRollbackWindow : Window
|
||||
{
|
||||
private class VersionItem
|
||||
{
|
||||
public string Version { get; set; }
|
||||
public string DownloadUrl { get; set; }
|
||||
public string ReleaseNotes { get; set; }
|
||||
}
|
||||
|
||||
private List<VersionItem> versionList = new List<VersionItem>();
|
||||
private VersionItem selectedItem = null;
|
||||
|
||||
public HistoryRollbackWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
LoadVersions();
|
||||
}
|
||||
|
||||
private async void LoadVersions()
|
||||
{
|
||||
RollbackButton.IsEnabled = false;
|
||||
VersionComboBox.Items.Clear();
|
||||
DownloadProgressPanel.Visibility = Visibility.Collapsed;
|
||||
DownloadProgressBar.Value = 0;
|
||||
DownloadProgressText.Text = "";
|
||||
ReleaseNotesViewer.Markdown = "正在获取历史版本...";
|
||||
var releases = await AutoUpdateHelper.GetAllGithubReleases();
|
||||
versionList.Clear();
|
||||
foreach (var (version, url, notes) in releases)
|
||||
{
|
||||
versionList.Add(new VersionItem { Version = version, DownloadUrl = url, ReleaseNotes = notes });
|
||||
}
|
||||
VersionComboBox.ItemsSource = versionList;
|
||||
if (versionList.Count > 0)
|
||||
{
|
||||
VersionComboBox.SelectedIndex = 0;
|
||||
RollbackButton.IsEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReleaseNotesViewer.Markdown = "未获取到历史版本信息。";
|
||||
}
|
||||
}
|
||||
|
||||
private void VersionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
selectedItem = VersionComboBox.SelectedItem as VersionItem;
|
||||
if (selectedItem != null)
|
||||
{
|
||||
ReleaseNotesViewer.Markdown = selectedItem.ReleaseNotes ?? "无更新日志";
|
||||
}
|
||||
}
|
||||
|
||||
private async void RollbackButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (selectedItem == null) return;
|
||||
RollbackButton.IsEnabled = false;
|
||||
VersionComboBox.IsEnabled = false;
|
||||
DownloadProgressPanel.Visibility = Visibility.Visible;
|
||||
DownloadProgressBar.Value = 0;
|
||||
DownloadProgressText.Text = "正在准备下载...";
|
||||
bool downloadSuccess = false;
|
||||
try
|
||||
{
|
||||
downloadSuccess = await DownloadAndInstallVersion(selectedItem.Version, selectedItem.DownloadUrl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DownloadProgressText.Text = $"下载失败: {ex.Message}";
|
||||
}
|
||||
if (downloadSuccess)
|
||||
{
|
||||
DownloadProgressBar.Value = 100;
|
||||
DownloadProgressText.Text = "下载完成,准备安装...";
|
||||
await Task.Delay(800);
|
||||
this.DialogResult = true;
|
||||
this.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
DownloadProgressText.Text = "下载失败,请检查网络后重试。";
|
||||
RollbackButton.IsEnabled = true;
|
||||
VersionComboBox.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> DownloadAndInstallVersion(string version, string downloadUrl)
|
||||
{
|
||||
string updatesFolderPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "AutoUpdate");
|
||||
if (!Directory.Exists(updatesFolderPath))
|
||||
Directory.CreateDirectory(updatesFolderPath);
|
||||
string zipFilePath = Path.Combine(updatesFolderPath, $"InkCanvasForClass.CE.{version}.zip");
|
||||
string tmpFilePath = zipFilePath + ".tmp";
|
||||
long existingLength = 0;
|
||||
if (File.Exists(tmpFilePath))
|
||||
existingLength = new FileInfo(tmpFilePath).Length;
|
||||
try
|
||||
{
|
||||
using (var client = new System.Net.Http.HttpClient())
|
||||
{
|
||||
client.Timeout = TimeSpan.FromMinutes(10);
|
||||
client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater");
|
||||
if (existingLength > 0)
|
||||
client.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(existingLength, null);
|
||||
using (var response = await client.GetAsync(downloadUrl, System.Net.Http.HttpCompletionOption.ResponseHeadersRead))
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
var totalBytes = response.Content.Headers.ContentLength.HasValue
|
||||
? response.Content.Headers.ContentLength.Value + existingLength
|
||||
: -1L;
|
||||
using (var stream = await response.Content.ReadAsStreamAsync())
|
||||
using (var fs = new FileStream(tmpFilePath, FileMode.Append, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
byte[] buffer = new byte[8192];
|
||||
long totalRead = existingLength;
|
||||
int read;
|
||||
var lastUpdate = DateTime.Now;
|
||||
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
await fs.WriteAsync(buffer, 0, read);
|
||||
totalRead += read;
|
||||
if ((DateTime.Now - lastUpdate).TotalMilliseconds > 200)
|
||||
{
|
||||
int percent = totalBytes > 0 ? (int)(totalRead * 100 / totalBytes) : 0;
|
||||
DownloadProgressBar.Value = percent;
|
||||
DownloadProgressText.Text = totalBytes > 0
|
||||
? $"已下载 {totalRead / 1024 / 1024.0:F2} MB / {totalBytes / 1024 / 1024.0:F2} MB ({percent}%)"
|
||||
: $"已下载 {totalRead / 1024 / 1024.0:F2} MB";
|
||||
lastUpdate = DateTime.Now;
|
||||
}
|
||||
}
|
||||
DownloadProgressBar.Value = 100;
|
||||
DownloadProgressText.Text = "下载完成,正在校验...";
|
||||
await fs.FlushAsync();
|
||||
}
|
||||
if (File.Exists(zipFilePath)) File.Delete(zipFilePath);
|
||||
File.Move(tmpFilePath, zipFilePath);
|
||||
}
|
||||
}
|
||||
// 下载完成后,调用现有安装流程
|
||||
AutoUpdateHelper.InstallNewVersionApp(version, false);
|
||||
App.IsAppExitByUser = true;
|
||||
Application.Current.Dispatcher.Invoke(() => {
|
||||
Application.Current.Shutdown();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (File.Exists(tmpFilePath)) { /* 不删除,便于断点续传 */ }
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,11 @@ none
|
||||
false
|
||||
TRACE;DEBUG;NETFRAMEWORK;NET472;;NET30_OR_GREATER;NET35_OR_GREATER;NET40_OR_GREATER;NET45_OR_GREATER;NET451_OR_GREATER;NET452_OR_GREATER;NET46_OR_GREATER;NET461_OR_GREATER;NET462_OR_GREATER;NET47_OR_GREATER;NET471_OR_GREATER;NET472_OR_GREATER
|
||||
E:\ICC CE\ICC CE main\community\Ink Canvas\App.xaml
|
||||
21348134359
|
||||
22-2143008179
|
||||
|
||||
752071346691
|
||||
76-141727233
|
||||
471037513499
|
||||
Helpers\Plugins\BuiltIn\SuperLauncher\LauncherSettingsControl.xaml;Helpers\Plugins\BuiltIn\SuperLauncher\LauncherWindow.xaml;MainWindow.xaml;MainWindow_cs\MW_Eraser.xaml;Resources\DrawShapeImageDictionary.xaml;Resources\IconImageDictionary.xaml;Resources\SeewoImageDictionary.xaml;Resources\Styles\Dark.xaml;Resources\Styles\Light.xaml;Windows\AddCustomIconWindow.xaml;Windows\AddPickNameBackgroundWindow.xaml;Windows\CountdownTimerWindow.xaml;Windows\CustomIconWindow.xaml;Windows\CycleProcessBar.xaml;Windows\HasNewUpdateWindow.xaml;Windows\ManagePickNameBackgroundsWindow.xaml;Windows\NamesInputWindow.xaml;Windows\OperatingGuideWindow.xaml;Windows\PluginSettingsWindow.xaml;Windows\RandWindow.xaml;Windows\YesOrNoNotificationWindow.xaml;
|
||||
Helpers\Plugins\BuiltIn\SuperLauncher\LauncherSettingsControl.xaml;Helpers\Plugins\BuiltIn\SuperLauncher\LauncherWindow.xaml;MainWindow.xaml;MainWindow_cs\MW_Eraser.xaml;Resources\DrawShapeImageDictionary.xaml;Resources\IconImageDictionary.xaml;Resources\SeewoImageDictionary.xaml;Resources\Styles\Dark.xaml;Resources\Styles\Light.xaml;Windows\AddCustomIconWindow.xaml;Windows\AddPickNameBackgroundWindow.xaml;Windows\CountdownTimerWindow.xaml;Windows\CustomIconWindow.xaml;Windows\CycleProcessBar.xaml;Windows\HasNewUpdateWindow.xaml;Windows\HistoryRollbackWindow.xaml;Windows\ManagePickNameBackgroundsWindow.xaml;Windows\NamesInputWindow.xaml;Windows\OperatingGuideWindow.xaml;Windows\PluginSettingsWindow.xaml;Windows\RandWindow.xaml;Windows\YesOrNoNotificationWindow.xaml;
|
||||
|
||||
False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user