Skip to content

Commit

Permalink
Add: 更新功能已完善
Browse files Browse the repository at this point in the history
  • Loading branch information
Miaoyww committed Feb 23, 2024
1 parent 911e405 commit 7c5bdd7
Show file tree
Hide file tree
Showing 18 changed files with 336 additions and 280 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
- name: Build
run: |
$sha = "${{ steps.sha.outputs.sha }}"
New-Item -Path "build/Starward/" -Type Directory
New-Item -Path "build/NonsPlayer/" -Type Directory
msbuild NonsPlayer.Launcher "-property:Configuration=$env:Configuration;Platform=$env:Platform;OutDir=$(Resolve-Path "build/NonsPlayer/")"
dotnet build NonsPlayer -c $env:Configuration -o "build/NonsPlayer/app-build.$sha" -p:Platform=$env:Platform -p:Version="0.0.1-build.$sha" -p:DefineConstants=CI
Add-Content "build/NonsPlayer/version.ini" -Value "app_folder=app-build.$sha`r`nexe_name=NonsPlayer.exe"
Expand Down
13 changes: 9 additions & 4 deletions NonsPlayer.Core/Services/ExpectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@ namespace NonsPlayer.Core.Services;

public class ExceptionService
{
public delegate void ExceptionThrewHandle(Exception exception);

public delegate void ExceptionThrewHandle(string content);

public static ExceptionService Instance { get; } = new();

public event ExceptionThrewHandle ExceptionThrew;

public void Throw(string content)
{
Debug.WriteLine($"抛出了一个异常: {content}");
ExceptionThrew?.Invoke(content);
}

public void Throw(Exception exception)
{
Debug.WriteLine($"抛出了一个异常: {exception}");
ExceptionThrew?.Invoke(exception);
ExceptionThrew?.Invoke(exception.Message);
}
}
2 changes: 1 addition & 1 deletion NonsPlayer.Updater/Metadata/LocalFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class LocalFile
public string To { get; set; }

public string Path { get; set; }

public string Hash { get; set; }

public bool IsMoving { get; set; }
Expand Down
12 changes: 12 additions & 0 deletions NonsPlayer.Updater/Metadata/MetadataJsonContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using NonsPlayer.Updater.Github;
using System.Text.Json.Serialization;

namespace NonsPlayer.Updater.Metadata;

[JsonSerializable(typeof(ReleaseVersion))]
[JsonSerializable(typeof(GithubRelease))]
[JsonSerializable(typeof(List<GithubRelease>))]
internal partial class MetadataJsonContext : JsonSerializerContext
{

}
1 change: 1 addition & 0 deletions NonsPlayer.Updater/NonsPlayer.Updater.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0"/>
<PackageReference Include="NuGet.Versioning" Version="6.9.1" />
<PackageReference Include="SevenZipExtractor" Version="1.0.17" />
</ItemGroup>

Expand Down
26 changes: 17 additions & 9 deletions NonsPlayer.Updater/Update/UpdateClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Runtime.InteropServices;
using System.Text.Json;
using NonsPlayer.Updater.Github;
using NonsPlayer.Updater.Metadata;

namespace NonsPlayer.Updater.Update;

Expand Down Expand Up @@ -33,7 +34,8 @@ private string GetUrl(string suffix)
}


public async Task<ReleaseVersion> GetLatestVersionAsync(bool isPrerelease, Architecture architecture)
public async Task<ReleaseVersion> GetLatestVersionAsync(bool isPrerelease, Architecture architecture,
CancellationToken cancellationToken = default)
{
#if DEV
isPrerelease = true;
Expand All @@ -47,21 +49,27 @@ public async Task<ReleaseVersion> GetLatestVersionAsync(bool isPrerelease, Archi
_ => throw new PlatformNotSupportedException($"{architecture} is not supported.")
};
var url = GetUrl(name);
return await ParseResponse<ReleaseVersion>(url);
return await ParseResponse<ReleaseVersion>(url, cancellationToken);
}

public async Task<GithubRelease?> GetGithubReleaseAsync(string tag)
public async Task<GithubRelease?> GetGithubReleaseAsync(string tag, CancellationToken cancellationToken = default)
{
var url = $"https://api.github.com/repos/Miaoyww/NonsPlayer/releases/tags/{tag}";
return await ParseResponse<GithubRelease>(url);
return await ParseResponse<GithubRelease>(url, cancellationToken);
}

private async Task<T> ParseResponse<T>(string url) where T : class
private async Task<T> ParseResponse<T>(string url, CancellationToken cancellationToken = default) where T : class
{
var res = await _httpClient.GetFromJsonAsync(url, typeof(T)) as T;
if (res == null) throw new NullReferenceException($"尝试ParseResponse失败,res为空.URL= {url}");

return res;
var res =
await _httpClient.GetFromJsonAsync(url, typeof(T), MetadataJsonContext.Default, cancellationToken) as T;
if (res == null)
{
throw new NullReferenceException($"尝试ParseResponse失败,res为空.URL= {url}");
}
else
{
return res;
}
}

public async Task<string> RenderGithubMarkdownAsync(string markdown, CancellationToken cancellationToken = default)
Expand Down
109 changes: 45 additions & 64 deletions NonsPlayer.Updater/Update/UpdateService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using NonsPlayer.Core.Services;
using NonsPlayer.Updater.Github;
using NonsPlayer.Updater.Metadata;
using NuGet.Versioning;
using SevenZipExtractor;

namespace NonsPlayer.Updater.Update;
Expand Down Expand Up @@ -42,16 +43,23 @@ public enum UpdateState

private ReleaseVersion _releaseVersion;

private string _updateFolder;
private string _appFolder;

private string _unzipFolder;

public long Progress_BytesToDownload { get; private set; }

private long progress_BytesDownloaded;
public long Progress_BytesDownloaded => progress_BytesDownloaded;


private int progress_FileCountDownloaded;

private List<LocalFile> localFiles;

private List<LocalFile> targetFiles;


public UpdateService(UpdateClient _inUpdateClient)
{
_httpClient = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.All })
Expand All @@ -60,24 +68,22 @@ public UpdateService(UpdateClient _inUpdateClient)
}

public UpdateState State { get; private set; }


public long Progress_BytesToDownload { get; private set; }
public long Progress_BytesDownloaded => progress_BytesDownloaded;



public string ErrorMessage { get; set; }


public async Task<ReleaseVersion?> CheckUpdateAsync(Version currentVersion, Architecture architecture,
public async Task<ReleaseVersion?> CheckUpdateAsync(string version, Architecture architecture,
bool enablePreviewRelease = false, bool disableIgnore = false)
{
NuGetVersion.TryParse(version, out var currentVersion);
// _logger.LogInformation("Start to check update (Preview: {preview}, Arch: {arch})", AppConfig.EnablePreviewRelease, RuntimeInformation.OSArchitecture);
var latestRelease = await _updateClient.GetLatestVersionAsync(enablePreviewRelease, architecture);
// _logger.LogInformation("Current version: {0}, latest version: {1}, ignore version: {2}", AppConfig.AppVersion, release?.Version, ignoreVersion);
Version? latestVersion;
Version.TryParse(latestRelease.Version, out latestVersion);
if (currentVersion.CompareTo(latestVersion) < 0) return latestRelease;
NuGetVersion.TryParse(latestRelease.Version, out var latestVersion);
if (latestVersion! > currentVersion!)
{
return latestRelease;
}

return null;
}
Expand All @@ -93,11 +99,8 @@ public async Task PrepareForUpdateAsync(ReleaseVersion release)
ErrorMessage = string.Empty;
_releaseVersion = release;
State = UpdateState.Preparing;
_updateFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"NonsPlayer\\data");
_unzipFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"NonsPlayer\\data\\unzip");
Directory.CreateDirectory(_updateFolder);
_appFolder = AppContext.BaseDirectory;
_unzipFolder = Path.Combine(_appFolder, "unzip");
GetDownloadFile();
progress_BytesDownloaded = 0;
Progress_BytesToDownload = _downloadFile.Release.PortableSize;
Expand All @@ -113,7 +116,7 @@ public async Task PrepareForUpdateAsync(ReleaseVersion release)

private void GetDownloadFile()
{
var targetFilePath = Path.Combine(_updateFolder,
var targetFilePath = Path.Combine(_appFolder,
$"NonsPlayer_Portable_{_releaseVersion.Version}_{_releaseVersion.Architecture}.7z");
var localFile = new LocalFile
{
Expand Down Expand Up @@ -151,15 +154,17 @@ public void Stop()
}


public async Task UpdateAsync()
public async Task UpdateAsync(CancellationToken cancellationToken = default)
{
try
{
progress_BytesDownloaded = 0;
Progress_BytesToDownload = _downloadFile.Release.PortableSize;
cancelSource?.Cancel();
cancelSource = new CancellationTokenSource();
var source = cancelSource;
State = UpdateState.Downloading;
await DownloadFilesAsync(source.Token);
await DownloadFileAsync(_downloadFile, source.Token);
if (source.IsCancellationRequested) throw new TaskCanceledException();

var check = CheckDownloadFile();
Expand All @@ -172,8 +177,7 @@ public async Task UpdateAsync()
await Task.Run(() =>
{
UnzipFile();
GetUnzipFiles();
MovingFiles();
MovingFolder();
});
State = UpdateState.Finish;
}
Expand All @@ -190,14 +194,6 @@ await Task.Run(() =>
}


private async Task DownloadFilesAsync(CancellationToken cancellationToken = default)
{
progress_BytesDownloaded = 0;
Progress_BytesToDownload = _downloadFile.Release.PortableSize;
await DownloadFileAsync(_downloadFile, cancellationToken);
}


private async Task DownloadFileAsync(ReleaseFile releaseFile, CancellationToken cancellationToken = default)
{
var readLength = 0;
Expand Down Expand Up @@ -225,6 +221,7 @@ private async Task DownloadFileAsync(ReleaseFile releaseFile, CancellationToken
}

await File.WriteAllBytesAsync(file, ms.ToArray(), cancellationToken);
Interlocked.Increment(ref progress_FileCountDownloaded);
}

using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Expand Down Expand Up @@ -262,52 +259,36 @@ private bool CheckDownloadFile()

private void UnzipFile()
{
Directory.CreateDirectory(Path.GetDirectoryName(_downloadFile.File.To)!);
Directory.CreateDirectory(_appFolder);
using (var archiveFile = new ArchiveFile(_downloadFile.File.Path))
{
archiveFile.Extract(_downloadFile.File.To);
}
}

private void GetUnzipFiles()
private void MovingFolder()
{
if (targetFiles == null)
try
{
var files = Directory.GetFiles(_downloadFile.File.To, "*", SearchOption.AllDirectories);
var releaseFiles = new List<LocalFile>(files.Length);
foreach (var file in files)
{
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
var len = (int)fs.Length;
var bytes = ArrayPool<byte>.Shared.Rent(len);
fs.Read(bytes, 0, len);
var span = bytes.AsSpan(0, len);
var sha256 = SHA256.HashData(span);
ArrayPool<byte>.Shared.Return(bytes);
releaseFiles.Add(new LocalFile
{
Path = file,
To = Path.Combine(AppContext.BaseDirectory, Path.GetFileName(file)),
Hash = Convert.ToHexString(sha256)
});
var tagertFolder = new DirectoryInfo(AppContext.BaseDirectory).Parent?.FullName;
var appVersionFolder = $"app-{_downloadFile.Release.Version}";
File.Copy(Path.Combine(_unzipFolder, "NonsPlayer", "version.ini"),
Path.Combine(tagertFolder, "version.ini"),
overwrite: true);
var launcherFile = Path.Combine(tagertFolder, "NonsPlayer.exe");
if (!File.Exists(launcherFile))
{
File.Copy(Path.Combine(_unzipFolder, "NonsPlayer", "NonsPlayer.exe"),
launcherFile,
overwrite: true);
}

targetFiles = releaseFiles;

Directory.Move(Path.Combine(_unzipFolder, "NonsPlayer", appVersionFolder),
Path.Combine(tagertFolder, appVersionFolder));
}
}

private void MovingFiles()
{
foreach (var file in targetFiles)
catch (Exception ex)
{
if (file.IsMoving)
{
File.Move(file.Path, file.To, true);
}
else
{
File.Copy(file.Path, file.To, true);
}
ExceptionService.Instance.Throw("更新失败~建议手动下载并覆盖");
}
}

Expand Down
10 changes: 10 additions & 0 deletions NonsPlayer.sln
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,18 @@ Global
{803AEE18-AC5A-426D-B41A-D5115C5F9A58}.Release|x86.Deploy.0 = Release|x86
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Debug|arm64.ActiveCfg = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Debug|arm64.Build.0 = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Debug|x64.ActiveCfg = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Debug|x64.Build.0 = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Debug|x86.ActiveCfg = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Debug|x86.Build.0 = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Release|Any CPU.Build.0 = Release|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Release|arm64.ActiveCfg = Release|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Release|arm64.Build.0 = Release|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Release|x64.ActiveCfg = Release|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Release|x64.Build.0 = Release|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Release|x86.ActiveCfg = Debug|Any CPU
{4F8E4835-D244-4999-8ACC-8F1A2D9DD8E1}.Release|x86.Build.0 = Debug|Any CPU
{750DDD97-204B-46EB-90DC-17148DA7D785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
Expand Down
1 change: 1 addition & 0 deletions NonsPlayer/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public App()
services.AddSingleton<VersionService>();
services.AddSingleton<UpdateService>();
services.AddSingleton<UpdateClient>();
services.AddSingleton<ExceptionService>();
// Core Services
services.AddSingleton<IFileService, FileService>();
Expand Down
Loading

0 comments on commit 7c5bdd7

Please sign in to comment.