migration
This commit is contained in:
parent
561881c9aa
commit
f133c740e1
55 changed files with 2928 additions and 20 deletions
167
test/Discovery.Loader.Avalonia/Services/UpdateService.cs
Normal file
167
test/Discovery.Loader.Avalonia/Services/UpdateService.cs
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
using Discovery.Loader.Models;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
|
||||
namespace Discovery.Loader.Services;
|
||||
|
||||
public class UpdateService
|
||||
{
|
||||
public DirectoryInfo AppDir { get; private set; }
|
||||
|
||||
public UpdateService()
|
||||
{
|
||||
var localApps = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
|
||||
|
||||
AppDir = new(Path.Combine(localApps.FullName + @"\Discovery"));
|
||||
}
|
||||
|
||||
public bool IsInstalled()
|
||||
{
|
||||
if (!AppDir.Exists)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AppDir.EnumerateFiles().Where(p => p.Name.Contains("Discovery.exe", StringComparison.InvariantCultureIgnoreCase)).Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<Update?> GetUpdateAsync()
|
||||
{
|
||||
using var httpClient = new HttpClient();
|
||||
|
||||
var update = await httpClient.GetFromJsonAsync(
|
||||
"https://raw.githubusercontent.com/vaitr/discovery/refs/heads/main/version.json",
|
||||
UpdateContext.Default.Update,
|
||||
default);
|
||||
|
||||
if (update == null)
|
||||
{
|
||||
Console.WriteLine("Source not available");
|
||||
return null;
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
public bool CompareVersion(Update update)
|
||||
{
|
||||
Console.WriteLine(update.Version);
|
||||
Console.WriteLine(update.Link);
|
||||
|
||||
var mainExecutable = new FileInfo(Path.Combine(AppDir.FullName + @"/discovery.exe"));
|
||||
if (!mainExecutable.Exists)
|
||||
return false;
|
||||
|
||||
var currentVersion = FileVersionInfo.GetVersionInfo(mainExecutable.FullName).FileVersion;
|
||||
|
||||
var vCurrent = Version.Parse(currentVersion!);
|
||||
var vUpdate = Version.Parse(update.Version);
|
||||
|
||||
if (vUpdate > vCurrent)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> DownloadAsync(Update update, Func<double, Task>? onProgress)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var httpClient = new HttpClient();
|
||||
httpClient.Timeout = TimeSpan.FromMinutes(3);
|
||||
|
||||
using var fileStream = new FileStream(Path.Combine(AppDir.FullName + @"/update.zip"), FileMode.Create);
|
||||
|
||||
// Get the http headers first to examine the content length
|
||||
using var response = await httpClient.GetAsync(update.Link, HttpCompletionOption.ResponseHeadersRead);
|
||||
var contentLength = response.Content.Headers.ContentLength;
|
||||
|
||||
using var download = await response.Content.ReadAsStreamAsync(default);
|
||||
|
||||
if (onProgress == null || !contentLength.HasValue)
|
||||
{
|
||||
await download.CopyToAsync(fileStream);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Convert absolute progress (bytes downloaded) into relative progress (0% - 100%)
|
||||
var relativeProgress = new Progress<long>(async (totalBytes) =>
|
||||
{
|
||||
Console.WriteLine(totalBytes + " / " + contentLength.Value + " / " + (float)totalBytes / contentLength.Value);
|
||||
await onProgress((float)totalBytes / contentLength.Value);
|
||||
});
|
||||
|
||||
// Use extension method to report progress while downloading
|
||||
await download.CopyToAsync(fileStream, 81920, relativeProgress, default);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Extract()
|
||||
{
|
||||
var archivePath = Path.Combine(AppDir.FullName + @"/update.zip");
|
||||
|
||||
using (var archive = ZipFile.OpenRead(archivePath))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var file = new FileInfo(Path.Combine(AppDir.FullName, entry.Name));
|
||||
if (file.Exists)
|
||||
file.Delete();
|
||||
|
||||
entry.ExtractToFile(file.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
File.Delete(archivePath);
|
||||
}
|
||||
|
||||
public void StartExecutable()
|
||||
{
|
||||
var exec = new FileInfo(Path.Combine(AppDir.FullName + @"/discovery.exe"));
|
||||
_ = Process.Start(new ProcessStartInfo
|
||||
{
|
||||
UseShellExecute = true,
|
||||
FileName = exec.FullName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static class StreamExtensions
|
||||
{
|
||||
public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
if (!source.CanRead)
|
||||
throw new ArgumentException("Has to be readable", nameof(source));
|
||||
if (destination == null)
|
||||
throw new ArgumentNullException(nameof(destination));
|
||||
if (!destination.CanWrite)
|
||||
throw new ArgumentException("Has to be writable", nameof(destination));
|
||||
if (bufferSize < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(bufferSize));
|
||||
|
||||
var buffer = new byte[bufferSize];
|
||||
long totalBytesRead = 0;
|
||||
int bytesRead;
|
||||
while ((bytesRead = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) != 0)
|
||||
{
|
||||
await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
|
||||
totalBytesRead += bytesRead;
|
||||
progress?.Report(totalBytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue