First update UI layout

This commit is contained in:
ema 2024-12-18 20:27:22 +08:00
parent dd19afaca5
commit 6b0746d2bd
14 changed files with 632 additions and 71 deletions

View File

@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BetterGenshinImpact.Test",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fischless.WindowsInput", "Fischless.WindowsInput\Fischless.WindowsInput.csproj", "{9D00BC7A-9280-4AC9-8951-4502EDB71B76}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Updater", "Build\Updater\Updater.csproj", "{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -123,6 +125,14 @@ Global
{9D00BC7A-9280-4AC9-8951-4502EDB71B76}.Release|Any CPU.Build.0 = Release|x64
{9D00BC7A-9280-4AC9-8951-4502EDB71B76}.Release|x64.ActiveCfg = Release|x64
{9D00BC7A-9280-4AC9-8951-4502EDB71B76}.Release|x64.Build.0 = Release|x64
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}.Debug|x64.ActiveCfg = Debug|Any CPU
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}.Debug|x64.Build.0 = Debug|Any CPU
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}.Release|Any CPU.Build.0 = Release|Any CPU
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}.Release|x64.ActiveCfg = Release|Any CPU
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -130,6 +140,7 @@ Global
GlobalSection(NestedProjects) = preSolution
{AB85DA23-EB8F-4FBF-A7FA-35CE05B23C15} = {458E1106-43A4-47E6-B11B-D243035D4C76}
{673344BC-B860-44AE-AD88-D33465BDE25B} = {458E1106-43A4-47E6-B11B-D243035D4C76}
{F18CF5A3-A83C-4CC6-8150-D3C40EC3140F} = {458E1106-43A4-47E6-B11B-D243035D4C76}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {352D8B78-9DE3-4E58-985F-FADD22594DB4}

View File

@ -10,8 +10,8 @@ using BetterGenshinImpact.View;
using BetterGenshinImpact.View.Pages;
using BetterGenshinImpact.ViewModel;
using BetterGenshinImpact.ViewModel.Pages;
using BetterGenshinImpact.ViewModel.Pages.View;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
@ -22,9 +22,6 @@ using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using BetterGenshinImpact.View.Pages.View;
using BetterGenshinImpact.ViewModel.Pages.OneDragon;
using BetterGenshinImpact.ViewModel.Pages.View;
using Wpf.Ui;
using Wpf.Ui.Violeta.Controls;
@ -77,6 +74,7 @@ public partial class App : Application
services.AddHostedService<ApplicationHostService>();
// Page resolver service
services.AddSingleton<IPageService, PageService>();
services.AddSingleton<IUpdateService, UpdateService>();
// Service containing navigation, same as INavigationWindow... but without window
services.AddSingleton<INavigationService, NavigationService>();

View File

@ -42,6 +42,7 @@
<ItemGroup>
<PackageReference Include="AvalonEdit" Version="6.3.0.90" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="Downloader" Version="3.3.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
@ -71,7 +72,7 @@
<PackageReference Include="Vanara.PInvoke.User32" Version="4.0.2" />
<PackageReference Include="WPF-UI" Version="3.0.5" />
<PackageReference Include="WPF-UI.Tray" Version="3.0.5" />
<PackageReference Include="WPF-UI.Violeta" Version="3.0.5.23" />
<PackageReference Include="WPF-UI.Violeta" Version="3.0.5.26" />
<PackageReference Include="YoloV8" Version="4.1.7" />
<PackageReference Include="gong-wpf-dragdrop" Version="3.2.1" />
</ItemGroup>

View File

@ -0,0 +1,12 @@
namespace BetterGenshinImpact.Model;
public sealed class UpdateOption
{
public UpdateTrigger Trigger { get; set; } = default;
}
public enum UpdateTrigger
{
Auto,
Manual,
}

View File

@ -0,0 +1,13 @@
using BetterGenshinImpact.Model;
using System.Threading.Tasks;
namespace BetterGenshinImpact.Service.Interface;
public interface IUpdateService
{
/// <summary>
/// I will check the update and completed the update if needed
/// </summary>
/// <returns></returns>
public Task CheckUpdateAsync(UpdateOption option);
}

View File

@ -0,0 +1,307 @@
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Helpers;
using BetterGenshinImpact.Helpers.Http;
using BetterGenshinImpact.Model;
using BetterGenshinImpact.Service.Interface;
using BetterGenshinImpact.Threading;
using BetterGenshinImpact.View.Windows;
using Downloader;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace BetterGenshinImpact.Service;
public class UpdateService : IUpdateService
{
private readonly ILogger<UpdateService> _logger;
private readonly IConfigService _configService;
private const string InstallationUrlPrefix = "https://raw.githubusercontent.com/bettergi/bettergi-installation-data/refs/heads/main/installation";
private const string HashUrl = "https://raw.githubusercontent.com/bettergi/bettergi-installation-data/refs/heads/main/hash.json";
private const string NoticUrl = "https://hui-config.oss-cn-hangzhou.aliyuncs.com/bgi/notice.json";
private const string DownloadPageUrl = "https://bgi.huiyadan.com/download.html";
public AllConfig Config { get; set; }
public UpdateService(IConfigService configService)
{
_logger = App.GetLogger<UpdateService>();
_configService = configService;
Config = _configService.Get();
}
private class XYZ
{
public string X { get; set; } = string.Empty;
public string Y { get; set; } = string.Empty;
public string Z { get; set; } = string.Empty;
}
/// <summary>
/// Please call me in main thread
/// </summary>
/// <param name="option"></param>
public async Task CheckUpdateAsync(UpdateOption option)
{
try
{
string newVersion = await GetLatestVersionAsync();
#if DEBUG && true
newVersion = "256.256.256.256";
#endif
if (string.IsNullOrWhiteSpace(newVersion))
{
return;
}
if (!Global.IsNewVersion(newVersion))
{
return;
}
if (!string.IsNullOrEmpty(Config.NotShowNewVersionNoticeEndVersion)
&& !Global.IsNewVersion(Config.NotShowNewVersionNoticeEndVersion, newVersion))
{
return;
}
CheckUpdateWindow win = new()
{
Owner = Application.Current.MainWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Title = $"发现新版本 {newVersion}",
UserInteraction = async (sender, button) =>
{
CheckUpdateWindow win = (CheckUpdateWindow)sender;
CancellationTokenSource? tokenSource = new();
switch (button)
{
case CheckUpdateWindow.CheckUpdateWindowButton.BackgroundUpdate:
// TBD
break;
case CheckUpdateWindow.CheckUpdateWindowButton.OtherUpdate:
Process.Start(new ProcessStartInfo(DownloadPageUrl) { UseShellExecute = true });
break;
case CheckUpdateWindow.CheckUpdateWindowButton.Update:
{
win.ShowUpdateStatus = true;
try
{
win.UpdateStatusMessage = "正在获取更新代理...";
(string fastProxyUrl, string jsonString) = await ProxySpeedTester.GetFastestProxyAsync(HashUrl);
win.UpdateStatusMessage = $"获取更新代理成功 {fastProxyUrl.Replace("{0}", string.Empty)}";
Dictionary<string, string>? hashDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString);
if (hashDict == null)
{
win.UpdateStatusMessage = "获取更新列表失败,更新已取消。";
return;
}
List<(string, string, string)> downloadList = [];
foreach (KeyValuePair<string, string> hashPair in hashDict)
{
string targetFileName = Path.GetFullPath($@".\update\{hashPair.Key}.zip");
string sourceFileName = Path.GetFullPath($@".\{hashPair.Value}");
if (IsNeedDownload(sourceFileName, hashPair.Value))
{
string url = string.Format(fastProxyUrl, $"{InstallationUrlPrefix}/{hashPair.Key}.zip").Replace("\\", "/");
downloadList.Add((hashPair.Key, url, targetFileName));
}
}
SemaphoreSlimParallel downloadParallel = await SemaphoreSlimParallel.ForEach(downloadList, async item =>
{
DownloadConfiguration downloadOpt = new();
DownloadService downloader = new(downloadOpt);
//downloader.DownloadFileCompleted += (sender, e) =>
//{
// if (e.Error != null)
// {
// _logger.LogError(e.Error, "下载失败");
// win.UpdateStatusMessage = $"下载失败:{e.Error.Message}";
// }
//};
(string shortName, string url, string fileName) = item;
win.UpdateStatusMessage = $"正在下载 {shortName}";
await downloader.DownloadFileTaskAsync(url, fileName, cancellationToken: tokenSource.Token);
win.UpdateStatusMessage = $"正在解压 {shortName}";
}, 3);
await downloadParallel.DisposeAsync();
win.UpdateStatusMessage = "下载已完成";
}
catch (Exception e)
{
_logger.LogError(e, "更新失败");
win.UpdateStatusMessage = $"更新失败:{e.Message}";
}
}
break;
case CheckUpdateWindow.CheckUpdateWindowButton.Ignore:
Config.NotShowNewVersionNoticeEndVersion = newVersion;
win.Close();
break;
case CheckUpdateWindow.CheckUpdateWindowButton.Cancel:
if (tokenSource != null)
{
if (MessageBox.Question("正在更新中,确定要取消更新吗?") == MessageBoxResult.Yes)
{
win.ShowUpdateStatus = false;
tokenSource?.Cancel();
win.Close();
}
}
else
{
win.ShowUpdateStatus = false;
win.Close();
}
break;
}
}
};
win.NavigateToHtml(await GetReleaseMarkdownHtmlAsync());
win.ShowDialog();
}
catch (Exception e)
{
Debug.WriteLine("获取最新版本信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
_logger.LogWarning("获取 BetterGI 最新版本信息失败");
}
}
private async Task<string> GetLatestVersionAsync()
{
try
{
using HttpClient httpClient = new();
Notice? notice = await httpClient.GetFromJsonAsync<Notice>(NoticUrl);
if (notice != null)
{
return notice.Version;
}
}
catch (Exception e)
{
_ = e;
}
return string.Empty;
}
private async Task<string> GetReleaseMarkdownHtmlAsync()
{
try
{
using HttpClient httpClient = new();
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
string jsonString = await httpClient.GetStringAsync("https://api.github.com/repos/babalae/better-genshin-impact/releases/latest");
var jsonDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
if (jsonDict != null)
{
string? name = jsonDict["name"] as string;
string? body = jsonDict["body"] as string;
string md = $"# {name}{new string('\n', 2)}{body}";
md = WebUtility.HtmlEncode(md);
string md2html = ResourceHelper.GetString($"pack://application:,,,/Assets/Strings/md2html.html", Encoding.UTF8);
var html = md2html.Replace("{{content}}", md);
return html;
}
}
catch (Exception e)
{
_ = e;
}
return GetReleaseMarkdownHtmlFallback();
}
private string GetReleaseMarkdownHtmlFallback()
{
return
"""
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<style>
body {
background-color: #212121;
color: white;
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.message {
text-align: center;
font-size: 20px;
}
</style>
</head>
<body>
<div class="message">
</div>
</body>
</html>
""";
}
private static bool IsNeedDownload(string sourceFileName, string targetSha256)
{
if (File.Exists(sourceFileName))
{
using SHA256 sha256 = SHA256.Create();
using FileStream fileStream = new(sourceFileName, FileMode.Open, FileAccess.Read);
byte[] hashBytes = sha256.ComputeHash(fileStream);
string sourceSha256 = BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToUpper();
if (sourceSha256 == targetSha256)
{
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace BetterGenshinImpact.Threading;
public class SemaphoreSlimParallel : IAsyncDisposable
{
private readonly SemaphoreSlim _semaphore;
private readonly List<Task> _tasks = [];
private SemaphoreSlimParallel(int maxDegreeOfParallelism)
{
_semaphore = new SemaphoreSlim(maxDegreeOfParallelism);
}
public static async Task<SemaphoreSlimParallel> ForEach<T>(
IEnumerable<T> items,
Func<T, Task> action,
int maxDegreeOfParallelism,
CancellationToken cancellationToken = default)
{
var parallelExecutor = new SemaphoreSlimParallel(maxDegreeOfParallelism);
foreach (var item in items)
{
await parallelExecutor._semaphore.WaitAsync(cancellationToken);
var task = Task.Run(async () =>
{
try
{
await action(item);
}
finally
{
parallelExecutor._semaphore.Release();
}
}, cancellationToken);
parallelExecutor._tasks.Add(task);
}
return parallelExecutor;
}
public async ValueTask DisposeAsync()
{
try
{
// 等待所有任务完成
await Task.WhenAll(_tasks);
}
finally
{
_semaphore.Dispose();
}
}
}

View File

@ -1,5 +1,4 @@
using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using System;
using System.Diagnostics;

View File

@ -1,7 +1,6 @@
using System;
using Microsoft.Web.WebView2.Wpf;
using System;
using System.Windows;
using System.Windows.Media;
using Microsoft.Web.WebView2.Wpf;
using Wpf.Ui.Controls;
namespace BetterGenshinImpact.View.Controls.Webview;
@ -20,7 +19,6 @@ public class WebpageWindow : Window
};
Content = wp;
// Background = new SolidColorBrush(Color.FromRgb(0x20, 0x20, 0x20));
}
protected override void OnSourceInitialized(EventArgs e)

View File

@ -0,0 +1,74 @@
<ui:FluentWindow x:Class="BetterGenshinImpact.View.Windows.CheckUpdateWindow"
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:local="clr-namespace:BetterGenshinImpact.View.Windows"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:vio="http://schemas.lepo.co/wpfui/2022/xaml/violeta"
xmlns:webview="clr-namespace:BetterGenshinImpact.View.Controls.Webview"
x:Name="app"
Title="发现新版本"
Width="680"
Height="450"
Background="#202020"
ExtendsContentIntoTitleBar="True"
FontFamily="{DynamicResource TextThemeFontFamily}"
WindowBackdropType="None"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d">
<Grid>
<ui:Grid Margin="0,48,0,0" RowDefinitions="Auto,*,Auto">
<webview:WebpagePanel x:Name="WebpagePanel"
Grid.Row="1"
Margin="12,0,12,0" />
<ui:Grid Grid.Row="0"
Margin="16,0,16,0"
ColumnDefinitions="Auto,*"
Visibility="{Binding ShowUpdateStatus, Converter={StaticResource BooleanToVisibilityConverter}}">
<vio:Loading Grid.Column="0" />
<ui:StackPanel Grid.Column="1" Margin="16,0,0,0">
<TextBlock Text="{Binding UpdateStatusMessage}" />
</ui:StackPanel>
</ui:Grid>
<ui:Grid Grid.Row="2"
Margin="8"
ColumnDefinitions="*,Auto,Auto,Auto,Auto">
<ui:Button Grid.Column="0"
MinWidth="90"
Margin="8,0,8,0"
Command="{Binding BackgroundUpdateCommand}"
Content="后台更新"
Visibility="Collapsed" />
<ui:Button Grid.Column="0"
MinWidth="90"
Margin="8,0,8,0"
Command="{Binding OtherUpdateCommand}"
Content="其他更新方式..." />
<ui:Button Grid.Column="1"
MinWidth="90"
Margin="8,0,8,0"
Appearance="Success"
Command="{Binding UpdateCommand}"
Content="立即更新" />
<ui:Button Grid.Column="2"
MinWidth="90"
Margin="8,0,8,0"
Command="{Binding IgnoreCommand}"
Content="不再提示" />
<ui:Button Grid.Column="3"
MinWidth="90"
Margin="8,0,8,0"
Command="{Binding CancelCommand}"
Content="取消" />
</ui:Grid>
</ui:Grid>
<ui:TitleBar Title="{Binding Title, ElementName=app}"
ShowMaximize="False"
ShowMinimize="False">
<ui:TitleBar.Icon>
<ui:ImageIcon Source="pack://application:,,,/Assets/Images/logo.png" />
</ui:TitleBar.Icon>
</ui:TitleBar>
</Grid>
</ui:FluentWindow>

View File

@ -0,0 +1,95 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using Wpf.Ui.Controls;
namespace BetterGenshinImpact.View.Windows;
[ObservableObject]
public partial class CheckUpdateWindow : FluentWindow
{
public Func<object, CheckUpdateWindowButton, Task> UserInteraction = null!;
[ObservableProperty]
private bool showUpdateStatus = false;
[ObservableProperty]
private string updateStatusMessage = string.Empty;
public CheckUpdateWindow()
{
DataContext = this;
InitializeComponent();
Closing += OnClosing;
}
protected void OnClosing(object? sender, CancelEventArgs e)
{
if (ShowUpdateStatus)
{
e.Cancel = true;
}
}
public void NavigateToHtml(string html)
{
WebpagePanel?.NavigateToHtml(html);
}
[RelayCommand]
private async Task BackgroundUpdateAsync()
{
if (UserInteraction != null)
{
await UserInteraction.Invoke(this, CheckUpdateWindowButton.BackgroundUpdate);
}
}
[RelayCommand]
private async Task OtherUpdateAsync()
{
if (UserInteraction != null)
{
await UserInteraction.Invoke(this, CheckUpdateWindowButton.OtherUpdate);
}
}
[RelayCommand]
private async Task UpdateAsync()
{
if (UserInteraction != null)
{
await UserInteraction.Invoke(this, CheckUpdateWindowButton.Update);
}
}
[RelayCommand]
private async Task IgnoreAsync()
{
if (UserInteraction != null)
{
await UserInteraction.Invoke(this, CheckUpdateWindowButton.Ignore);
}
}
[RelayCommand]
private async Task CancelAsync()
{
if (UserInteraction != null)
{
await UserInteraction.Invoke(this, CheckUpdateWindowButton.Cancel);
}
}
public enum CheckUpdateWindowButton
{
BackgroundUpdate,
OtherUpdate,
Update,
Ignore,
Cancel,
}
}

View File

@ -14,8 +14,6 @@ using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using System.Windows;
using Wpf.Ui;
@ -100,15 +98,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
MessageBox.Warning("PaddleOcr预热失败解决方案https://bgi.huiyadan.com/faq.html" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
}
try
{
await Task.Run(GetNewestInfoAsync);
}
catch (Exception e)
{
Debug.WriteLine("获取最新版本信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
_logger.LogWarning("获取 BetterGI 最新版本信息失败");
}
await App.GetService<IUpdateService>()!.CheckUpdateAsync(new UpdateOption());
// Win11下 BitBlt截图方式不可用需要关闭窗口优化功能
if (OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt)
@ -119,53 +109,4 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
// 更新仓库
ScriptRepoUpdater.Instance.AutoUpdate();
}
private async Task GetNewestInfoAsync()
{
try
{
using var httpClient = new HttpClient();
var notice = await httpClient.GetFromJsonAsync<Notice>(@"https://hui-config.oss-cn-hangzhou.aliyuncs.com/bgi/notice.json");
if (notice != null && !string.IsNullOrWhiteSpace(notice.Version))
{
if (Global.IsNewVersion(notice.Version))
{
if (!string.IsNullOrEmpty(Config.NotShowNewVersionNoticeEndVersion)
&& !Global.IsNewVersion(Config.NotShowNewVersionNoticeEndVersion, notice.Version))
{
return;
}
await UIDispatcherHelper.Invoke(async () =>
{
var uiMessageBox = new Wpf.Ui.Controls.MessageBox
{
Title = "更新提示",
Content = $"存在最新版本 {notice.Version},点击确定前往下载页面下载最新版本",
PrimaryButtonText = "确定",
SecondaryButtonText = "不再提示",
CloseButtonText = "取消",
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Owner = Application.Current.MainWindow,
};
var result = await uiMessageBox.ShowDialogAsync();
if (result == Wpf.Ui.Controls.MessageBoxResult.Primary)
{
Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/download.html") { UseShellExecute = true });
}
else if (result == Wpf.Ui.Controls.MessageBoxResult.Secondary)
{
Config.NotShowNewVersionNoticeEndVersion = notice.Version;
}
});
}
}
}
catch (Exception e)
{
Debug.WriteLine("获取最新版本信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
_logger.LogWarning("获取 BetterGI 最新版本信息失败");
}
}
}

44
Build/Updater/Program.cs Normal file
View File

@ -0,0 +1,44 @@
using System;
using System.IO;
using System.Threading;
namespace Updater;
internal sealed class Program
{
private static void Main(string[] args)
{
if (args.Length < 2)
{
// Avoid user interaction
Environment.ExitCode = 1;
return;
}
// Chattering ms
Thread.Sleep(200);
string sourcePath = args[0];
string targetPath = args[1];
if (!Directory.Exists(sourcePath))
{
Environment.ExitCode = 1;
return;
}
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
// No fallback measures
foreach (string file in Directory.GetFiles(sourcePath))
{
string fileName = Path.GetFileName(file);
string targetFile = Path.Combine(targetPath, fileName);
File.Copy(file, targetFile, true);
}
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net472</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
</Project>