improve:自动更新
This commit is contained in:
@@ -645,8 +645,10 @@
|
|||||||
Width="120" HorizontalAlignment="Left" Click="FixVersionButton_Click"/>
|
Width="120" HorizontalAlignment="Left" Click="FixVersionButton_Click"/>
|
||||||
<TextBlock Text="# 版本修复会根据当前选择的通道下载最新版本并执行安装,可用于修复损坏的安装"
|
<TextBlock Text="# 版本修复会根据当前选择的通道下载最新版本并执行安装,可用于修复损坏的安装"
|
||||||
TextWrapping="Wrap" Foreground="#a1a1aa" />
|
TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||||
|
<Button x:Name="HistoryRollbackButton" Content="历史版本回滚" Width="120" Margin="0,10,0,0" Click="HistoryRollbackButton_Click"/>
|
||||||
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Padding="12"
|
<TextBlock Text="# 历史版本回滚,点击后会弹出相应页面供用户手动回滚"
|
||||||
|
TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||||
|
<Border BorderBrush="White" BorderThickness="1" CornerRadius="5" Padding="12"
|
||||||
Visibility="{Binding ElementName=ToggleSwitchIsAutoUpdateWithSilence, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
|
Visibility="{Binding ElementName=ToggleSwitchIsAutoUpdateWithSilence, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
<ui:SimpleStackPanel Spacing="12">
|
<ui:SimpleStackPanel Spacing="12">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -655,12 +657,12 @@
|
|||||||
<ui:SimpleStackPanel x:Name="AutoUpdateTimePeriodBlock" Spacing="12">
|
<ui:SimpleStackPanel x:Name="AutoUpdateTimePeriodBlock" Spacing="12">
|
||||||
<ui:SimpleStackPanel Spacing="12">
|
<ui:SimpleStackPanel Spacing="12">
|
||||||
<TextBlock Text="静默更新时间段" FontSize="15" FontWeight="Bold"
|
<TextBlock Text="静默更新时间段" FontSize="15" FontWeight="Bold"
|
||||||
TextWrapping="Wrap" Foreground="Black" />
|
TextWrapping="Wrap" Foreground="#fafafa" />
|
||||||
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="12">
|
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="12">
|
||||||
<ui:SimpleStackPanel Orientation="Horizontal">
|
<ui:SimpleStackPanel Orientation="Horizontal">
|
||||||
<TextBlock Margin="0,0,10,0" VerticalAlignment="Center"
|
<TextBlock Margin="0,0,10,0" VerticalAlignment="Center"
|
||||||
Text="起始时间" FontSize="14" TextWrapping="Wrap"
|
Text="起始时间" FontSize="14" TextWrapping="Wrap"
|
||||||
Foreground="Black" />
|
Foreground="#fafafa" />
|
||||||
<ComboBox x:Name="AutoUpdateWithSilenceStartTimeComboBox"
|
<ComboBox x:Name="AutoUpdateWithSilenceStartTimeComboBox"
|
||||||
Width="90"
|
Width="90"
|
||||||
SelectionChanged="AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged" />
|
SelectionChanged="AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged" />
|
||||||
@@ -668,7 +670,7 @@
|
|||||||
<ui:SimpleStackPanel Orientation="Horizontal">
|
<ui:SimpleStackPanel Orientation="Horizontal">
|
||||||
<TextBlock Margin="0,0,10,0" VerticalAlignment="Center"
|
<TextBlock Margin="0,0,10,0" VerticalAlignment="Center"
|
||||||
Text="终止时间" FontSize="14" TextWrapping="Wrap"
|
Text="终止时间" FontSize="14" TextWrapping="Wrap"
|
||||||
Foreground="Black" />
|
Foreground="#fafafa" />
|
||||||
<ComboBox x:Name="AutoUpdateWithSilenceEndTimeComboBox"
|
<ComboBox x:Name="AutoUpdateWithSilenceEndTimeComboBox"
|
||||||
Width="90"
|
Width="90"
|
||||||
SelectionChanged="AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged" />
|
SelectionChanged="AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged" />
|
||||||
|
|||||||
@@ -1329,5 +1329,17 @@ namespace Ink_Canvas {
|
|||||||
// 直接调用PPT放映结束按钮的逻辑
|
// 直接调用PPT放映结束按钮的逻辑
|
||||||
BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null);
|
BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HistoryRollbackButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// 收起设置面板(与插件面板一致)
|
||||||
|
BorderSettings.Visibility = Visibility.Hidden;
|
||||||
|
BorderSettingsMask.Visibility = Visibility.Hidden;
|
||||||
|
var win = new HistoryRollbackWindow(Settings.Startup.UpdateChannel);
|
||||||
|
win.ShowDialog();
|
||||||
|
// 可选:回滚窗口关闭后恢复设置面板显示
|
||||||
|
BorderSettings.Visibility = Visibility.Visible;
|
||||||
|
BorderSettingsMask.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,5 +49,5 @@ using System.Windows;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.7.1.10")]
|
[assembly: AssemblyVersion("1.7.1.9")]
|
||||||
[assembly: AssemblyFileVersion("1.7.1.10")]
|
[assembly: AssemblyFileVersion("1.7.1.9")]
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ using System.IO;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Linq; // Added for OrderByDescending
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ink_Canvas
|
namespace Ink_Canvas
|
||||||
{
|
{
|
||||||
@@ -19,83 +23,115 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
private List<VersionItem> versionList = new List<VersionItem>();
|
private List<VersionItem> versionList = new List<VersionItem>();
|
||||||
private VersionItem selectedItem = null;
|
private VersionItem selectedItem = null;
|
||||||
|
private UpdateChannel channel = UpdateChannel.Release;
|
||||||
|
private CancellationTokenSource downloadCts = null;
|
||||||
|
|
||||||
public HistoryRollbackWindow()
|
public HistoryRollbackWindow(UpdateChannel channel = UpdateChannel.Release)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
this.channel = channel;
|
||||||
LoadVersions();
|
LoadVersions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void LoadVersions()
|
private async void LoadVersions()
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 开始加载历史版本,通道: {channel}");
|
||||||
RollbackButton.IsEnabled = false;
|
RollbackButton.IsEnabled = false;
|
||||||
VersionComboBox.Items.Clear();
|
VersionComboBox.Items.Clear();
|
||||||
DownloadProgressPanel.Visibility = Visibility.Collapsed;
|
DownloadProgressPanel.Visibility = Visibility.Collapsed;
|
||||||
DownloadProgressBar.Value = 0;
|
DownloadProgressBar.Value = 0;
|
||||||
DownloadProgressText.Text = "";
|
DownloadProgressText.Text = "";
|
||||||
ReleaseNotesViewer.Markdown = "正在获取历史版本...";
|
ReleaseNotesViewer.Markdown = "正在获取历史版本...";
|
||||||
var releases = await AutoUpdateHelper.GetAllGithubReleases();
|
var releases = await AutoUpdateHelper.GetAllGithubReleases(channel);
|
||||||
versionList.Clear();
|
versionList.Clear();
|
||||||
foreach (var (version, url, notes) in releases)
|
foreach (var (version, url, notes) in releases)
|
||||||
{
|
{
|
||||||
versionList.Add(new VersionItem { Version = version, DownloadUrl = url, ReleaseNotes = notes });
|
versionList.Add(new VersionItem { Version = version, DownloadUrl = url, ReleaseNotes = notes });
|
||||||
}
|
}
|
||||||
|
// 按版本号数字降序排列
|
||||||
|
versionList = versionList.OrderByDescending(v => ParseVersionForSort(v.Version)).ToList();
|
||||||
VersionComboBox.ItemsSource = versionList;
|
VersionComboBox.ItemsSource = versionList;
|
||||||
if (versionList.Count > 0)
|
if (versionList.Count > 0)
|
||||||
{
|
{
|
||||||
VersionComboBox.SelectedIndex = 0;
|
VersionComboBox.SelectedIndex = 0;
|
||||||
RollbackButton.IsEnabled = true;
|
RollbackButton.IsEnabled = true;
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 加载到 {versionList.Count} 个历史版本");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReleaseNotesViewer.Markdown = "未获取到历史版本信息。";
|
ReleaseNotesViewer.Markdown = "未获取到历史版本信息。";
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 未获取到历史版本信息", LogHelper.LogType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 辅助方法:解析版本号用于排序
|
||||||
|
private Version ParseVersionForSort(string version)
|
||||||
|
{
|
||||||
|
var v = version.TrimStart('v', 'V');
|
||||||
|
Version result;
|
||||||
|
if (Version.TryParse(v, out result))
|
||||||
|
return result;
|
||||||
|
return new Version(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private void VersionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void VersionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
selectedItem = VersionComboBox.SelectedItem as VersionItem;
|
selectedItem = VersionComboBox.SelectedItem as VersionItem;
|
||||||
if (selectedItem != null)
|
if (selectedItem != null)
|
||||||
{
|
{
|
||||||
ReleaseNotesViewer.Markdown = selectedItem.ReleaseNotes ?? "无更新日志";
|
ReleaseNotesViewer.Markdown = selectedItem.ReleaseNotes ?? "无更新日志";
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 用户选择版本: {selectedItem.Version}");
|
||||||
}
|
}
|
||||||
|
// 取消聚焦,防止父级自动滚动
|
||||||
|
Keyboard.ClearFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void RollbackButton_Click(object sender, RoutedEventArgs e)
|
private async void RollbackButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (selectedItem == null) return;
|
if (selectedItem == null) return;
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 用户点击回滚,目标版本: {selectedItem.Version}");
|
||||||
RollbackButton.IsEnabled = false;
|
RollbackButton.IsEnabled = false;
|
||||||
VersionComboBox.IsEnabled = false;
|
VersionComboBox.IsEnabled = false;
|
||||||
DownloadProgressPanel.Visibility = Visibility.Visible;
|
DownloadProgressPanel.Visibility = Visibility.Visible;
|
||||||
DownloadProgressBar.Value = 0;
|
DownloadProgressBar.Value = 0;
|
||||||
DownloadProgressText.Text = "正在准备下载...";
|
DownloadProgressText.Text = "正在准备下载...";
|
||||||
bool downloadSuccess = false;
|
bool downloadSuccess = false;
|
||||||
|
downloadCts = new CancellationTokenSource();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
downloadSuccess = await DownloadAndInstallVersion(selectedItem.Version, selectedItem.DownloadUrl);
|
downloadSuccess = await DownloadAndInstallVersion(selectedItem.Version, selectedItem.DownloadUrl, downloadCts.Token);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
DownloadProgressText.Text = "下载已取消。";
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 用户取消下载", LogHelper.LogType.Info);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DownloadProgressText.Text = $"下载失败: {ex.Message}";
|
DownloadProgressText.Text = $"下载失败: {ex.Message}";
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 下载异常: {ex.Message}", LogHelper.LogType.Error);
|
||||||
}
|
}
|
||||||
if (downloadSuccess)
|
if (downloadSuccess)
|
||||||
{
|
{
|
||||||
DownloadProgressBar.Value = 100;
|
DownloadProgressBar.Value = 100;
|
||||||
DownloadProgressText.Text = "下载完成,准备安装...";
|
DownloadProgressText.Text = "下载完成,准备安装...";
|
||||||
await Task.Delay(800);
|
await Task.Delay(800);
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 版本 {selectedItem.Version} 下载并准备安装成功");
|
||||||
this.DialogResult = true;
|
this.DialogResult = true;
|
||||||
this.Close();
|
this.Close();
|
||||||
}
|
}
|
||||||
else
|
else if (!downloadCts.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
DownloadProgressText.Text = "下载失败,请检查网络后重试。";
|
DownloadProgressText.Text = "下载失败,请检查网络后重试。";
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 版本 {selectedItem?.Version} 下载失败", LogHelper.LogType.Error);
|
||||||
RollbackButton.IsEnabled = true;
|
RollbackButton.IsEnabled = true;
|
||||||
VersionComboBox.IsEnabled = true;
|
VersionComboBox.IsEnabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> DownloadAndInstallVersion(string version, string downloadUrl)
|
private async Task<bool> DownloadAndInstallVersion(string version, string downloadUrl, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 开始下载版本: {version}, url: {downloadUrl}");
|
||||||
string updatesFolderPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "AutoUpdate");
|
string updatesFolderPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "AutoUpdate");
|
||||||
if (!Directory.Exists(updatesFolderPath))
|
if (!Directory.Exists(updatesFolderPath))
|
||||||
Directory.CreateDirectory(updatesFolderPath);
|
Directory.CreateDirectory(updatesFolderPath);
|
||||||
@@ -112,7 +148,7 @@ namespace Ink_Canvas
|
|||||||
client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater");
|
client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater");
|
||||||
if (existingLength > 0)
|
if (existingLength > 0)
|
||||||
client.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(existingLength, null);
|
client.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(existingLength, null);
|
||||||
using (var response = await client.GetAsync(downloadUrl, System.Net.Http.HttpCompletionOption.ResponseHeadersRead))
|
using (var response = await client.GetAsync(downloadUrl, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, token))
|
||||||
{
|
{
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
var totalBytes = response.Content.Headers.ContentLength.HasValue
|
var totalBytes = response.Content.Headers.ContentLength.HasValue
|
||||||
@@ -125,9 +161,10 @@ namespace Ink_Canvas
|
|||||||
long totalRead = existingLength;
|
long totalRead = existingLength;
|
||||||
int read;
|
int read;
|
||||||
var lastUpdate = DateTime.Now;
|
var lastUpdate = DateTime.Now;
|
||||||
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0)
|
||||||
{
|
{
|
||||||
await fs.WriteAsync(buffer, 0, read);
|
token.ThrowIfCancellationRequested();
|
||||||
|
await fs.WriteAsync(buffer, 0, read, token);
|
||||||
totalRead += read;
|
totalRead += read;
|
||||||
if ((DateTime.Now - lastUpdate).TotalMilliseconds > 200)
|
if ((DateTime.Now - lastUpdate).TotalMilliseconds > 200)
|
||||||
{
|
{
|
||||||
@@ -141,13 +178,14 @@ namespace Ink_Canvas
|
|||||||
}
|
}
|
||||||
DownloadProgressBar.Value = 100;
|
DownloadProgressBar.Value = 100;
|
||||||
DownloadProgressText.Text = "下载完成,正在校验...";
|
DownloadProgressText.Text = "下载完成,正在校验...";
|
||||||
await fs.FlushAsync();
|
await fs.FlushAsync(token);
|
||||||
}
|
}
|
||||||
if (File.Exists(zipFilePath)) File.Delete(zipFilePath);
|
if (File.Exists(zipFilePath)) File.Delete(zipFilePath);
|
||||||
File.Move(tmpFilePath, zipFilePath);
|
File.Move(tmpFilePath, zipFilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 下载完成后,调用现有安装流程
|
// 下载完成后,调用现有安装流程
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 开始安装版本: {version}");
|
||||||
AutoUpdateHelper.InstallNewVersionApp(version, false);
|
AutoUpdateHelper.InstallNewVersionApp(version, false);
|
||||||
App.IsAppExitByUser = true;
|
App.IsAppExitByUser = true;
|
||||||
Application.Current.Dispatcher.Invoke(() => {
|
Application.Current.Dispatcher.Invoke(() => {
|
||||||
@@ -155,11 +193,23 @@ namespace Ink_Canvas
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 用户取消下载", LogHelper.LogType.Info);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (File.Exists(tmpFilePath)) { /* 不删除,便于断点续传 */ }
|
if (File.Exists(tmpFilePath)) { /* 不删除,便于断点续传 */ }
|
||||||
|
LogHelper.WriteLogToFile($"HistoryRollback | 下载或安装异常: {ex.Message}", LogHelper.LogType.Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnClosing(CancelEventArgs e)
|
||||||
|
{
|
||||||
|
downloadCts?.Cancel();
|
||||||
|
base.OnClosing(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user