-
-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Preliminary version update functionality.
- Loading branch information
Showing
9 changed files
with
316 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace PicView.Avalonia.Update; | ||
|
||
public class UpdateInfo | ||
{ | ||
public string Version { get; set; } | ||
public string X64Portable { get; set; } | ||
public string X64Install { get; set; } | ||
public string Arm64Portable { get; set; } | ||
public string Arm64Install { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
using System.Diagnostics; | ||
using System.Runtime.InteropServices; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using Microsoft.Win32; | ||
using PicView.Avalonia.UI; | ||
using PicView.Avalonia.ViewModels; | ||
using PicView.Core.Config; | ||
using PicView.Core.FileHandling; | ||
|
||
namespace PicView.Avalonia.Update; | ||
|
||
[JsonSourceGenerationOptions(AllowTrailingCommas = true)] | ||
[JsonSerializable(typeof(UpdateInfo))] | ||
public partial class UpdateSourceGenerationContext : JsonSerializerContext; | ||
|
||
public static class UpdateManager | ||
{ | ||
public static void CheckForUpdates() | ||
{ | ||
} | ||
|
||
public static async Task UpdateCurrentVersion(MainViewModel vm) | ||
{ | ||
var currentDirectory = new DirectoryInfo(Environment.ProcessPath); | ||
var currentVersion = VersionHelper.GetCurrentVersionAsVersion(); | ||
var url = "https://picview.org/update.json"; | ||
var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + "PicView"); | ||
Directory.CreateDirectory(tempPath); | ||
var tempJsonFileDestination = Path.Combine(tempPath, "update.json"); | ||
|
||
#if DEBUG | ||
// Change it to lower to test it | ||
currentVersion = new Version("3.0.0.3"); | ||
#endif | ||
|
||
// Download the JSON file | ||
using var jsonFileDownloader = new HttpHelper.HttpClientDownloadWithProgress(url, tempJsonFileDestination); | ||
try | ||
{ | ||
await jsonFileDownloader.StartDownloadAsync(); | ||
} | ||
catch (Exception e) | ||
{ | ||
#if DEBUG | ||
Console.WriteLine(e); | ||
#endif | ||
await TooltipHelper.ShowTooltipMessageAsync(e.Message); | ||
return; | ||
} | ||
|
||
// Read and deserialize the JSON | ||
UpdateInfo? updateInfo; | ||
try | ||
{ | ||
var jsonString = await File.ReadAllTextAsync(tempJsonFileDestination); | ||
if (JsonSerializer.Deserialize( | ||
jsonString, typeof(UpdateInfo), | ||
UpdateSourceGenerationContext.Default) is not UpdateInfo serializedUpdateInfo) | ||
{ | ||
#if DEBUG | ||
Console.WriteLine("Update information is missing or corrupted."); | ||
#endif | ||
await TooltipHelper.ShowTooltipMessageAsync("Update information is missing or corrupted."); | ||
return; | ||
} | ||
|
||
updateInfo = serializedUpdateInfo; | ||
} | ||
catch (Exception e) | ||
{ | ||
#if DEBUG | ||
Console.WriteLine(e); | ||
#endif | ||
await TooltipHelper.ShowTooltipMessageAsync("Failed to parse update information: \n" + e.Message); | ||
return; | ||
} | ||
|
||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
{ | ||
var isAdmin = false; | ||
try | ||
{ | ||
isAdmin = currentDirectory.GetAccessControl().AreAccessRulesProtected; | ||
} | ||
catch (Exception) | ||
{ | ||
isAdmin = false; | ||
} | ||
|
||
var isInstalled = CheckIfIsInstalled(); | ||
|
||
var architecture = RuntimeInformation.ProcessArchitecture switch | ||
{ | ||
Architecture.X64 => isInstalled ? InstalledArchitecture.X64Install : InstalledArchitecture.X64Portable, | ||
Architecture.Arm64 => isInstalled | ||
? InstalledArchitecture.Arm64Install | ||
: InstalledArchitecture.Arm64Portable, | ||
_ => InstalledArchitecture.X64Install | ||
}; | ||
|
||
var remoteVersion = new Version(updateInfo.Version); | ||
if (remoteVersion <= currentVersion) | ||
{ | ||
return; | ||
} | ||
|
||
if (isAdmin) | ||
{ | ||
// Restart the application as admin | ||
var process = new Process | ||
{ | ||
StartInfo = new ProcessStartInfo | ||
{ | ||
Verb = "runas", | ||
UseShellExecute = true, | ||
FileName = "PicView.exe", | ||
Arguments = $"update,{architecture},{currentVersion},{tempPath}", | ||
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory | ||
} | ||
}; | ||
process.Start(); | ||
Environment.Exit(0); | ||
} | ||
else | ||
{ | ||
switch (architecture) | ||
{ | ||
case InstalledArchitecture.Arm64Install: | ||
var fileName = Path.GetFileName(updateInfo.X64Install); | ||
var tempFileDownloadPath = Path.Combine(tempPath, fileName); | ||
await StartFileDownloader(vm, updateInfo.Arm64Install, tempFileDownloadPath); | ||
var process = new Process | ||
{ | ||
StartInfo = new ProcessStartInfo | ||
{ | ||
Verb = "runas", | ||
UseShellExecute = true, | ||
FileName = tempFileDownloadPath | ||
} | ||
}; | ||
process.Start(); | ||
return; | ||
case InstalledArchitecture.Arm64Portable: | ||
fileName = Path.GetFileName(updateInfo.X64Portable); | ||
tempFileDownloadPath = Path.Combine(tempPath, fileName); | ||
await StartFileDownloader(vm, updateInfo.Arm64Portable, tempFileDownloadPath); | ||
vm.PlatformService.LocateOnDisk(tempFileDownloadPath); | ||
return; | ||
case InstalledArchitecture.X64Install: | ||
fileName = Path.GetFileName(updateInfo.X64Install); | ||
tempFileDownloadPath = Path.Combine(tempPath, fileName); | ||
await StartFileDownloader(vm, updateInfo.X64Install, tempFileDownloadPath); | ||
process = new Process | ||
{ | ||
StartInfo = new ProcessStartInfo | ||
{ | ||
Verb = "runas", | ||
UseShellExecute = true, | ||
FileName = tempFileDownloadPath | ||
} | ||
}; | ||
process.Start(); | ||
return; | ||
case InstalledArchitecture.X64Portable: | ||
fileName = Path.GetFileName(updateInfo.X64Portable); | ||
tempFileDownloadPath = Path.Combine(tempPath, fileName); | ||
await StartFileDownloader(vm, updateInfo.X64Portable, tempFileDownloadPath); | ||
vm.PlatformService.LocateOnDisk(tempFileDownloadPath); | ||
return; | ||
} | ||
} | ||
} | ||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) | ||
{ | ||
// TODO | ||
} | ||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) | ||
{ | ||
// TODO | ||
} | ||
} | ||
|
||
private static bool CheckIfIsInstalled() | ||
{ | ||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
{ | ||
return false; | ||
} | ||
|
||
var x64Path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "PicView.exe"; | ||
if (File.Exists(x64Path)) | ||
{ | ||
return true; | ||
} | ||
|
||
const string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; | ||
try | ||
{ | ||
using var key = Registry.LocalMachine.OpenSubKey(registryKey); | ||
if (key == null) | ||
{ | ||
return false; | ||
} | ||
|
||
foreach (var subKeyName in key.GetSubKeyNames()) | ||
{ | ||
using var subKey = key.OpenSubKey(subKeyName); | ||
|
||
var installDir = subKey?.GetValue("InstallLocation")?.ToString(); | ||
if (installDir == null) | ||
{ | ||
continue; | ||
} | ||
|
||
return Path.Exists(Path.Combine(installDir, "PicView.exe")); | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
#if DEBUG | ||
Trace.WriteLine($"{nameof(CheckIfIsInstalled)} exception, \n {e.Message}"); | ||
#endif | ||
return false; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
private static async Task StartFileDownloader(MainViewModel vm, string downloadUrl, string tempPath) | ||
{ | ||
vm.PlatformService.StopTaskbarProgress(); | ||
using var jsonFileDownloader = new HttpHelper.HttpClientDownloadWithProgress(downloadUrl, tempPath); | ||
try | ||
{ | ||
jsonFileDownloader.ProgressChanged += (size, downloaded, percentage) => | ||
ProgressChanged(vm, size, downloaded, percentage); | ||
await jsonFileDownloader.StartDownloadAsync(); | ||
} | ||
catch (Exception e) | ||
{ | ||
#if DEBUG | ||
Console.WriteLine(e); | ||
#endif | ||
await TooltipHelper.ShowTooltipMessageAsync(e.Message); | ||
} | ||
finally | ||
{ | ||
vm.PlatformService.StopTaskbarProgress(); | ||
} | ||
} | ||
|
||
private static void ProgressChanged(MainViewModel vm, long? totalfilesize, long? totalbytesdownloaded, double? progresspercentage) | ||
{ | ||
if (totalfilesize is null || totalbytesdownloaded is null || progresspercentage is null) | ||
{ | ||
return; | ||
} | ||
vm.PlatformService.SetTaskbarProgress((ulong)totalbytesdownloaded, (ulong)totalfilesize); | ||
} | ||
|
||
private enum InstalledArchitecture | ||
{ | ||
X64Portable, | ||
X64Install, | ||
Arm64Portable, | ||
Arm64Install | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.