返回提交历史
Modified
XFEToolBox.Client.Installer/App.xaml.cs
+17
-3
Modified
XFEToolBox.Client.Installer/Profiles/SystemProfile.cs
+6
-1
Modified
XFEToolBox.Client.Installer/README.md
+10
-0
Modified
XFEToolBox.Client.Installer/ViewModel/Pages/InstallPageViewModel.cs
+2
-2
Modified
XFEToolBox.Client.Installer/ViewModel/Pages/InstallProgressPageViewModel.cs
+1
-1
Modified
XFEToolBox.Client.Installer/Views/Pages/InstallProgressPage.xaml.cs
+4
-3
Modified
XFEToolBox.Client.Installer/XFEToolBox.Client.Installer.csproj
+1
-0
Modified
XFEToolBox/Profiles/CrossVersionProfiles/SystemProfile.cs
+10
-0
Modified
XFEToolBox/Utilities/PopupHelper.cs
+8
-2
Added
XFEToolBox/Utilities/UpgradeHelper.cs
+108
-0
Added
XFEToolBox/Utilities/UpgradeService.cs
+203
-0
Modified
XFEToolBox/ViewModel/Pages/SettingPageViewModel.cs
+42
-0
Modified
XFEToolBox/Views/Pages/SettingPage.xaml
+22
-0
Modified
XFEToolBox/Views/Windows/MainWindow.xaml.cs
+3
-0
Modified
XFEToolBox/XFEToolBox.Client.csproj
+2
-1
XFEstudio/XFEToolBox
新增 XFEToolBox 在线升级检测与一键升级功能
- 实现升级协议与流程,集成 UpgradeHelper/UpgradeService,支持自动/手动检测新版本、发行说明弹窗、忽略版本管理 - 设置页新增“软件更新”分组,支持手动检查、自动检测开关、当前版本显示、忽略版本清理等 - 主窗口支持启动时自动检测升级 - 统一 Installer 及主程序参数与路径,增强参数校验与异常提示 - README 增加升级协议说明,明确流程与参数格式 - 引入 XFEExtension.NetCore.UpgradeHelper 依赖,版本号提升至 1.1.0 - 优化弹窗辅助类及相关属性、命令、界面绑定
97019ed
代码差异
15 个文件
+439
-13
@@ -16,11 +16,25 @@ namespace XFEToolBox.Client.Installer
16
16
{
17
17
SystemProfile.FirstInstall = true;
18
18
}
19
else if (e.Args.Length == 3 &&
20
string.Equals(e.Args[0], "Upgrade", StringComparison.OrdinalIgnoreCase) &&
21
Uri.TryCreate(e.Args[1], UriKind.Absolute, out var parsedDownloadUri) &&
22
parsedDownloadUri is { } downloadUri &&
23
(downloadUri.Scheme == Uri.UriSchemeHttp || downloadUri.Scheme == Uri.UriSchemeHttps) &&
24
System.IO.Directory.Exists(e.Args[2]))
25
{
26
SystemProfile.StartMode = "Upgrade";
27
SystemProfile.DownloadUrl = downloadUri.AbsoluteUri;
28
SystemProfile.InstallPath = System.IO.Path.GetFullPath(e.Args[2]);
29
}
19
30
else
20
31
{
21
SystemProfile.StartMode = e.Args[0];
22
SystemProfile.DownloadUrl = e.Args[1];
23
SystemProfile.InstallPath = e.Args[2];
32
MessageBox.Show(
33
"Installer 收到的升级参数无效。请从 XFEToolBox 内重新检查更新。",
34
"无法开始升级",
35
MessageBoxButton.OK,
36
MessageBoxImage.Error);
37
Shutdown(-1);
24
38
}
25
39
}
26
40
}
@@ -2,6 +2,9 @@
2
2
{
3
3
public class SystemProfile
4
4
{
5
public const string ApplicationName = "XFEToolBox";
6
public const string ApplicationExecutableName = ApplicationName + ".exe";
7
5
8
/// <summary>
6
9
/// 当前窗口DPI缩放
7
10
/// </summary>
@@ -29,7 +32,9 @@
29
32
/// <summary>
30
33
/// 安装目录
31
34
/// </summary>
32
public static string InstallPath { get; set; } = @$"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)}\XFEToolBox.Client.Installer";
35
public static string InstallPath { get; set; } = System.IO.Path.Combine(
36
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
37
ApplicationName);
33
38
/// <summary>
34
39
/// 第一次安装
35
40
/// </summary>
@@ -16,3 +16,13 @@
16
16
## 将软件压缩包放入安装器
17
17
18
18
- 将完成上述操作后的软件打包为打包为`Source.zip`文件(请注意,压缩包内应为包含exe的直接目录,而非二级目录),并替换`Resources\Resource`目录下0KB的`Source.zip`文件
19
20
## 在线升级协议
21
22
- 客户端通过 `XFEExtension.NetCore.UpgradeHelper` 请求 `http://upgrade.api.xfe.studio/upgrade`,升级服务中的应用名固定为 `XFEToolBox`
23
- 检测到新版本并经用户确认后,客户端以管理员权限调用同目录的 `Installer.exe`
24
- 调用参数依次为:`Upgrade`、升级压缩包的 HTTP/HTTPS 地址、当前 XFEToolBox 安装目录
25
- 等价命令:`Installer.exe Upgrade <downloadUrl> <installDirectory>`
26
- Installer 会将压缩包下载为安装目录下的 `InstallPackage.zip`,解压覆盖完成后删除临时压缩包,并启动 `XFEToolBox.exe`
27
- 发布升级包时不要增加二级目录;压缩包根目录应直接包含 `XFEToolBox.exe` 及其依赖文件
28
- 在线升级包不要覆盖正在运行的 `Installer.exe`;Installer 自身需要更新时,应在后续安装包发布流程中单独替换
@@ -16,7 +16,7 @@ namespace XFEToolBox.Client.Installer.ViewModel.Pages
16
16
[ObservableProperty]
17
17
bool agreementChecked = false;
18
18
[ObservableProperty]
19
string installPath = @$"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)}\XFEToolBox.Client.Installer";
19
string installPath = SystemProfile.InstallPath;
20
20
public InstallPage ViewPage { get; set; } = viewPage;
21
21
22
22
[RelayCommand]
@@ -37,7 +37,7 @@ namespace XFEToolBox.Client.Installer.ViewModel.Pages
37
37
if (openFolderDialog.ShowDialog() == true)
38
38
{
39
39
if (FileHelper.IsRootPath(openFolderDialog.FolderName))
40
InstallPath = $@"{openFolderDialog.FolderName}XFEToolBox.Client.Installer";
40
InstallPath = Path.Combine(openFolderDialog.FolderName, SystemProfile.ApplicationName);
41
41
else
42
42
InstallPath = openFolderDialog.FolderName;
43
43
SystemProfile.InstallPath = InstallPath;
@@ -14,7 +14,7 @@ namespace XFEToolBox.Client.Installer.ViewModel.Pages
14
14
[RelayCommand]
15
15
void ConfirmSuccess()
16
16
{
17
var startInfo = new ProcessStartInfo(Path.Combine(SystemProfile.InstallPath, "XFE工具箱.exe"))
17
var startInfo = new ProcessStartInfo(Path.Combine(SystemProfile.InstallPath, SystemProfile.ApplicationExecutableName))
18
18
{
19
19
UseShellExecute = true,
20
20
WorkingDirectory = SystemProfile.InstallPath
@@ -30,9 +30,10 @@ namespace XFEToolBox.Client.Installer.Views.Pages
30
30
{
31
31
case "Upgrade":
32
32
var filePath = Path.Combine(SystemProfile.InstallPath, "InstallPackage.zip");
33
if (File.Exists(filePath) && File.OpenRead(filePath) is FileStream fileStream)
33
if (File.Exists(filePath))
34
34
{
35
Install(fileStream);
35
using (var fileStream = File.OpenRead(filePath))
36
Install(fileStream);
36
37
File.Delete(filePath);
37
38
}
38
39
break;
@@ -42,7 +43,7 @@ namespace XFEToolBox.Client.Installer.Views.Pages
42
43
if (SystemProfile.InstallPath != string.Empty && !Directory.Exists(SystemProfile.InstallPath))
43
44
Directory.CreateDirectory(SystemProfile.InstallPath);
44
45
if (Install(innerStream))
45
FileHelper.CreateShortCut($@"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\XFE工具箱.lnk", Path.Combine(SystemProfile.InstallPath, "XFEToolBox.exe"), null, "XFE工具箱快捷方式", null, SystemProfile.InstallPath);
46
FileHelper.CreateShortCut($@"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\XFE工具箱.lnk", Path.Combine(SystemProfile.InstallPath, SystemProfile.ApplicationExecutableName), null, "XFE工具箱快捷方式", null, SystemProfile.InstallPath);
46
47
}
47
48
break;
48
49
}
@@ -9,6 +9,7 @@
9
9
<ApplicationManifest>app.manifest</ApplicationManifest>
10
10
<ApplicationIcon>Resources\Icon\Icon.ico</ApplicationIcon>
11
11
<AssemblyName>Installer</AssemblyName>
12
<Version>1.1.0</Version>
12
13
</PropertyGroup>
13
14
14
15
<ItemGroup>
@@ -46,6 +46,16 @@ public partial class SystemProfile : XFEProfile
46
46
[ProfileProperty]
47
47
private bool mainTutorialCompleted = false;
48
48
/// <summary>
49
/// 是否在主窗口首次加载后自动检查新版本。
50
/// </summary>
51
[ProfileProperty]
52
private bool checkForUpdatesOnStartup = true;
53
/// <summary>
54
/// 用户选择忽略的升级版本。
55
/// </summary>
56
[ProfileProperty]
57
private string ignoredUpgradeVersion = string.Empty;
58
/// <summary>
49
59
/// 最近使用页面、工具和软件的 JSON 记录,由 RecentUsageService 维护。
50
60
/// </summary>
51
61
[ProfileProperty]
@@ -45,6 +45,9 @@ public static class PopupHelper
45
45
};
46
46
47
47
public static MessageBoxResult? ShowConfirmDialog(object content, bool showCancelButton = false, string confirmText = "确定", string cancelText = "取消")
48
=> ShowConfirmDialog(content, new PopupWindowOptions(), showCancelButton, confirmText, cancelText);
49
50
public static MessageBoxResult? ShowConfirmDialog(object content, PopupWindowOptions options, bool showCancelButton = false, string confirmText = "确定", string cancelText = "取消")
48
51
{
49
52
var dialog = CreateNormalDialogPage(content);
50
53
dialog.ViewModel.ConfirmText = confirmText;
@@ -52,7 +55,7 @@ public static class PopupHelper
52
55
dialog.ViewModel.ConfirmGridLength = new GridLength(1, GridUnitType.Star);
53
56
if (showCancelButton)
54
57
dialog.ViewModel.CancelGridLength = new GridLength(1, GridUnitType.Star);
55
return ShowDialog(dialog);
58
return ShowDialog(dialog, options);
56
59
}
57
60
58
61
public static MessageBoxResult? ShowConfirmDialog(string text, Color textColor, bool showCancelButton = false, string confirmText = "确定", string cancelText = "取消") => ShowConfirmDialog(CreateTextContent(text, textColor), showCancelButton, confirmText, cancelText);
@@ -60,6 +63,9 @@ public static class PopupHelper
60
63
public static MessageBoxResult? ShowConfirmDialog(string text, bool showCancelButton = false, string confirmText = "确定", string cancelText = "取消") => ShowConfirmDialog(text, Colors.Black, showCancelButton, confirmText, cancelText);
61
64
62
65
public static MessageBoxResult? ShowYesOrNoDialog(object content, bool showCancelButton = false, string yesText = "是", string noText = "否")
66
=> ShowYesOrNoDialog(content, new PopupWindowOptions(), showCancelButton, yesText, noText);
67
68
public static MessageBoxResult? ShowYesOrNoDialog(object content, PopupWindowOptions options, bool showCancelButton = false, string yesText = "是", string noText = "否")
63
69
{
64
70
var dialog = CreateNormalDialogPage(content);
65
71
dialog.ViewModel.YesText = yesText;
@@ -68,7 +74,7 @@ public static class PopupHelper
68
74
dialog.ViewModel.NoGridLength = new GridLength(1, GridUnitType.Star);
69
75
if (showCancelButton)
70
76
dialog.ViewModel.CancelGridLength = new GridLength(1, GridUnitType.Star);
71
return ShowDialog(dialog);
77
return ShowDialog(dialog, options);
72
78
}
73
79
74
80
public static MessageBoxResult? ShowYesOrNoDialog(string text, Color textColor, bool showCancelButton = false, string yesText = "是", string noText = "否") => ShowYesOrNoDialog(CreateTextContent(text, textColor), showCancelButton, yesText, noText);
@@ -0,0 +1,108 @@
1
using System.Diagnostics;
2
using System.IO;
3
using System.Reflection;
4
using ApplicationUpgradeManager.Core.Model;
5
using XFEExtension.NetCore.UpgradeHelper.Models;
6
using XFEExtension.NetCore.UpgradeHelper.Utilities;
7
8
namespace XFEToolBox.Client.Utilities;
9
10
/// <summary>
11
/// XFEToolBox 与 ApplicationUpgradeManager 服务之间的统一入口。
12
/// </summary>
13
public static class UpgradeHelper
14
{
15
public const string ApplicationName = "XFEToolBox";
16
public const string RequestAddress = "http://upgrade.api.xfe.studio/upgrade";
17
public const string InstallerFileName = "Installer.exe";
18
19
public static Upgrader Upgrader { get; set; } = new(RequestAddress);
20
21
public static Version Version => Assembly.GetEntryAssembly()?.GetName().Version ?? new Version(1, 0, 0);
22
23
public static string DisplayVersion => Version.ToString(3);
24
25
/// <summary>
26
/// 检查当前版本是否已经是最新版本。网络错误按“未知”处理,不阻断应用启动。
27
/// </summary>
28
public static async Task<bool> CheckUpgrade()
29
{
30
var release = await GetReleaseNotes();
31
return release?.IsLatest ?? true;
32
}
33
34
/// <summary>
35
/// 获取适合直接展示的发行说明。
36
/// </summary>
37
public static async Task<UpgradeInfoNotes?> GetReleaseNotes()
38
{
39
try
40
{
41
return await Upgrader.GetReleaseNotes(ApplicationName, Version.ToString());
42
}
43
catch (Exception exception)
44
{
45
Debug.WriteLine($"[Upgrade] 获取发行说明失败:{exception}");
46
return null;
47
}
48
}
49
50
/// <summary>
51
/// 获取结构化版本记录,供历史版本或高级界面使用。
52
/// </summary>
53
public static async Task<UpgradeInfoObject?> GetReleaseObject()
54
{
55
try
56
{
57
return await Upgrader.GetReleaseObject(ApplicationName, Version.ToString());
58
}
59
catch (Exception exception)
60
{
61
Debug.WriteLine($"[Upgrade] 获取结构化升级信息失败:{exception}");
62
return null;
63
}
64
}
65
66
/// <summary>
67
/// 创建 Installer 的升级启动参数。公开此方法便于发布流程和测试校验协议。
68
/// </summary>
69
public static ProcessStartInfo CreateInstallerStartInfo(
70
string downloadUrl,
71
string? installDirectory = null,
72
string? installerPath = null)
73
{
74
if (!Uri.TryCreate(downloadUrl, UriKind.Absolute, out var downloadUri) ||
75
(downloadUri.Scheme != Uri.UriSchemeHttp && downloadUri.Scheme != Uri.UriSchemeHttps))
76
throw new ArgumentException("升级下载地址必须是有效的 HTTP 或 HTTPS 地址。", nameof(downloadUrl));
77
78
installDirectory = Path.GetFullPath(installDirectory ?? AppContext.BaseDirectory);
79
installerPath = Path.GetFullPath(installerPath ?? Path.Combine(installDirectory, InstallerFileName));
80
if (!Directory.Exists(installDirectory))
81
throw new DirectoryNotFoundException($"找不到应用安装目录:{installDirectory}");
82
if (!File.Exists(installerPath))
83
throw new FileNotFoundException("找不到升级所需的 Installer.exe,请重新安装或修复 XFEToolBox。", installerPath);
84
85
var startInfo = new ProcessStartInfo(installerPath)
86
{
87
UseShellExecute = true,
88
Verb = "runas",
89
WorkingDirectory = installDirectory
90
};
91
startInfo.ArgumentList.Add("Upgrade");
92
startInfo.ArgumentList.Add(downloadUri.AbsoluteUri);
93
startInfo.ArgumentList.Add(installDirectory);
94
return startInfo;
95
}
96
97
/// <summary>
98
/// 以管理员权限启动 Installer,并关闭当前应用释放待替换文件。
99
/// </summary>
100
public static void StartUpdate(string downloadUrl)
101
{
102
var process = Process.Start(CreateInstallerStartInfo(downloadUrl));
103
if (process is null)
104
throw new InvalidOperationException("Installer 未能启动。");
105
106
AppCenter.ExitApp(true);
107
}
108
}
@@ -0,0 +1,203 @@
1
using System.Windows;
2
using System.Windows.Controls;
3
using System.Windows.Media;
4
using ApplicationUpgradeManager.Core.Model;
5
using XFEToolBox.Client.Model;
6
using XFEToolBox.Client.Profiles.CrossVersionProfiles;
7
8
namespace XFEToolBox.Client.Utilities;
9
10
public enum UpgradeCheckOutcome
11
{
12
Latest,
13
UpdateAvailable,
14
Ignored,
15
UpdateStarted,
16
Failed,
17
AlreadyChecking
18
}
19
20
public sealed record UpgradeCheckResult(
21
UpgradeCheckOutcome Outcome,
22
string Message,
23
UpgradeInfoNotes? Release = null);
24
25
/// <summary>
26
/// 协调自动/手动检查、版本忽略、升级提示和 Installer 启动。
27
/// </summary>
28
public static class UpgradeService
29
{
30
private static readonly SemaphoreSlim CheckGate = new(1, 1);
31
32
public static bool IsChecking => CheckGate.CurrentCount == 0;
33
34
public static async Task<UpgradeCheckResult> CheckForUpdatesAsync(bool userInitiated, Window? owner = null)
35
{
36
if (!await CheckGate.WaitAsync(0))
37
return new UpgradeCheckResult(UpgradeCheckOutcome.AlreadyChecking, "正在检查更新,请稍候。");
38
39
try
40
{
41
var release = await UpgradeHelper.GetReleaseNotes();
42
if (release is null)
43
{
44
const string message = "无法连接升级服务器,请检查网络后重试。";
45
if (userInitiated)
46
ShowInformation("检查更新失败", message, owner);
47
return new UpgradeCheckResult(UpgradeCheckOutcome.Failed, message);
48
}
49
50
if (release.IsLatest)
51
{
52
var message = $"当前已是最新版本({UpgradeHelper.DisplayVersion})。";
53
if (userInitiated)
54
ShowInformation("已是最新版本", message, owner);
55
return new UpgradeCheckResult(UpgradeCheckOutcome.Latest, message, release);
56
}
57
58
if (!userInitiated && string.Equals(
59
release.LatestVersion,
60
SystemProfile.IgnoredUpgradeVersion,
61
StringComparison.OrdinalIgnoreCase))
62
{
63
return new UpgradeCheckResult(
64
UpgradeCheckOutcome.Ignored,
65
$"版本 {release.LatestVersion} 已被忽略。",
66
release);
67
}
68
69
var choice = PopupHelper.ShowYesOrNoDialog(
70
CreateReleaseContent(release),
71
new PopupWindowOptions
72
{
73
Title = "发现新版本",
74
Subtitle = $"XFEToolBox {UpgradeHelper.DisplayVersion} → {release.LatestVersion}",
75
Width = 540,
76
Height = 390,
77
Owner = owner
78
},
79
showCancelButton: true,
80
yesText: "立即更新",
81
noText: "忽略此版本");
82
83
if (choice == MessageBoxResult.Yes)
84
{
85
try
86
{
87
UpgradeHelper.StartUpdate(release.DownloadUrl);
88
return new UpgradeCheckResult(UpgradeCheckOutcome.UpdateStarted, "Installer 已启动。", release);
89
}
90
catch (Exception exception)
91
{
92
var message = $"无法启动 Installer:{exception.Message}";
93
ShowInformation("启动升级失败", message, owner);
94
return new UpgradeCheckResult(UpgradeCheckOutcome.Failed, message, release);
95
}
96
}
97
98
if (choice == MessageBoxResult.No)
99
{
100
SystemProfile.IgnoredUpgradeVersion = release.LatestVersion ?? string.Empty;
101
return new UpgradeCheckResult(
102
UpgradeCheckOutcome.Ignored,
103
$"已忽略版本 {release.LatestVersion},仍可在设置中手动检查。",
104
release);
105
}
106
107
return new UpgradeCheckResult(
108
UpgradeCheckOutcome.UpdateAvailable,
109
$"发现版本 {release.LatestVersion},已暂缓更新。",
110
release);
111
}
112
catch (Exception exception)
113
{
114
var message = $"检查更新时发生错误:{exception.Message}";
115
if (userInitiated)
116
ShowInformation("检查更新失败", message, owner);
117
return new UpgradeCheckResult(UpgradeCheckOutcome.Failed, message);
118
}
119
finally
120
{
121
CheckGate.Release();
122
}
123
}
124
125
private static FrameworkElement CreateReleaseContent(UpgradeInfoNotes release)
126
{
127
var notes = string.IsNullOrWhiteSpace(release.ReleaseNotes)
128
? "该版本暂未提供发行说明。"
129
: release.ReleaseNotes.Trim();
130
var title = new TextBlock
131
{
132
Text = $"可升级至 {release.LatestVersion}",
133
FontSize = 17,
134
FontWeight = FontWeights.SemiBold,
135
Margin = new Thickness(0, 0, 0, 6)
136
};
137
title.SetResourceReference(TextBlock.ForegroundProperty, "ToolTextPrimaryBrush");
138
139
var hint = new TextBlock
140
{
141
Text = "升级将调用同目录下的 Installer,下载完成后替换当前程序文件。",
142
TextWrapping = TextWrapping.Wrap,
143
Margin = new Thickness(0, 0, 0, 12)
144
};
145
hint.SetResourceReference(TextBlock.ForegroundProperty, "ToolTextSecondaryBrush");
146
147
var releaseText = new TextBlock
148
{
149
Text = notes,
150
TextWrapping = TextWrapping.Wrap,
151
Padding = new Thickness(14),
152
LineHeight = 22
153
};
154
releaseText.SetResourceReference(TextBlock.ForegroundProperty, "ToolTextPrimaryBrush");
155
releaseText.SetResourceReference(TextBlock.BackgroundProperty, "ToolControlBackgroundBrush");
156
157
return new Grid
158
{
159
Margin = new Thickness(18, 14, 18, 12),
160
Children =
161
{
162
new StackPanel
163
{
164
Children =
165
{
166
title,
167
hint,
168
new ScrollViewer
169
{
170
MaxHeight = 205,
171
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
172
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
173
Content = releaseText
174
}
175
}
176
}
177
}
178
};
179
}
180
181
private static void ShowInformation(string title, string message, Window? owner)
182
{
183
var text = new TextBlock
184
{
185
Text = message,
186
TextWrapping = TextWrapping.Wrap,
187
Margin = new Thickness(18),
188
VerticalAlignment = VerticalAlignment.Center
189
};
190
text.SetResourceReference(TextBlock.ForegroundProperty, "ToolTextPrimaryBrush");
191
PopupHelper.ShowConfirmDialog(
192
text,
193
new PopupWindowOptions
194
{
195
Title = title,
196
Subtitle = "XFEToolBox 软件更新",
197
Width = 390,
198
Height = 230,
199
Owner = owner
200
},
201
confirmText: "知道了");
202
}
203
}
@@ -29,8 +29,16 @@ public partial class SettingPageViewModel(SettingPage viewPage) : ObservableObje
29
29
string totalProfileSize = "计算中...";
30
30
[ObservableProperty]
31
31
string downloadDirectory = "目标下载目录:";
32
[ObservableProperty]
33
string upgradeStatus = "可手动检查更新,也可在启动时自动检测新版本。";
34
[ObservableProperty]
35
string ignoredUpgradeVersionDisplay = GetIgnoredUpgradeVersionDisplay();
36
[ObservableProperty]
37
[NotifyCanExecuteChangedFor(nameof(CheckUpgradeCommand))]
38
bool isCheckingForUpdates;
32
39
bool ignoreNextScroll = false;
33
40
public SettingPage ViewPage { get; set; } = viewPage;
41
public string CurrentApplicationVersion => $"当前版本 {UpgradeHelper.DisplayVersion}";
34
42
35
43
public static void LoadSettingProfile(DependencyObject parent)
36
44
{
@@ -269,5 +277,39 @@ public partial class SettingPageViewModel(SettingPage viewPage) : ObservableObje
269
277
ViewPage.scrollViewer.ScrollToVerticalOffset(ViewPage.scrollViewer.VerticalOffset + textBlock.TranslatePoint(new(), ViewPage.scrollViewer).Y - 20);
270
278
}
271
279
}
280
281
private bool CanCheckUpgrade() => !IsCheckingForUpdates;
282
283
[RelayCommand(CanExecute = nameof(CanCheckUpgrade))]
284
async Task CheckUpgrade()
285
{
286
IsCheckingForUpdates = true;
287
UpgradeStatus = "正在连接升级服务器...";
288
try
289
{
290
var result = await UpgradeService.CheckForUpdatesAsync(
291
userInitiated: true,
292
owner: Window.GetWindow(ViewPage));
293
UpgradeStatus = result.Message;
294
IgnoredUpgradeVersionDisplay = GetIgnoredUpgradeVersionDisplay();
295
}
296
finally
297
{
298
IsCheckingForUpdates = false;
299
}
300
}
301
302
[RelayCommand]
303
void ClearIgnoredUpgradeVersion()
304
{
305
SystemProfile.IgnoredUpgradeVersion = string.Empty;
306
IgnoredUpgradeVersionDisplay = GetIgnoredUpgradeVersionDisplay();
307
UpgradeStatus = "已清除忽略记录,后续检查会再次提示所有新版本。";
308
}
309
310
private static string GetIgnoredUpgradeVersionDisplay() =>
311
string.IsNullOrWhiteSpace(SystemProfile.IgnoredUpgradeVersion)
312
? "未忽略任何版本"
313
: $"已忽略 {SystemProfile.IgnoredUpgradeVersion}";
272
314
#endregion
273
315
}