Check for updates on startup

This commit is contained in:
Yoshi Askharoun
2025-09-02 12:17:28 -07:00
parent d8f9a3cf44
commit 5f0b00cfa8
3 changed files with 161 additions and 119 deletions
+3
View File
@@ -45,6 +45,9 @@ namespace ZuneModdingHelper
{
await _settings.LoadAsync();
// Check for updates in the background
UpdateHelper.Instance.CheckForUpdatesAsync(false);
// Show a warning if Zune isn't found. Usually happens if Zune isn't installed,
// is installed in an unusual directory, or the user is running ZMH 32-bit
// on a 64-bit system.
+3 -119
View File
@@ -1,12 +1,5 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Syroot.Windows.IO;
using System;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Controls;
using System.Windows.Navigation;
using ZuneModdingHelper.Messages;
using ZuneModdingHelper.Services;
namespace ZuneModdingHelper.Pages
@@ -16,19 +9,13 @@ namespace ZuneModdingHelper.Pages
/// </summary>
public partial class AboutPage : UserControl
{
const string UPDATES_DIALOG_TITLE = "UPDATES";
private readonly IUpdateService? _updateService = Ioc.Default.GetService<IUpdateService>();
private UpdateAvailableInfo _updateInfo;
private string _downloadedUpdatePath;
public AboutPage()
{
DataContext = this;
InitializeComponent();
}
public bool EnableCheckForUpdates => _updateService is not null;
public bool EnableCheckForUpdates => UpdateHelper.Instance.Enabled;
private void Link_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
@@ -38,110 +25,7 @@ namespace ZuneModdingHelper.Pages
private async void UpdateCheckButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (_updateService is null)
return;
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(new ProgressDialogViewModel
{
Title = UPDATES_DIALOG_TITLE,
Description = "Checking for updates, please wait...",
IsIndeterminate = true,
ShowAffirmativeButton = false,
}));
try
{
_updateInfo = await _updateService.FetchAvailableUpdate();
if (_updateInfo is null)
{
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(new DialogViewModel
{
Title = UPDATES_DIALOG_TITLE,
Description = "No updates available.\r\n\r\nYou're already using the latest version.",
ShowAffirmativeButton = true,
}));
return;
}
// Newer version available, prompt user to download
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(new DialogViewModel
{
Title = UPDATES_DIALOG_TITLE,
Description = $"Release {_updateInfo.Name} is available. Would you like to download it now?",
AffirmativeText = "YES",
NegativeText = "NO",
ShowAffirmativeButton = true,
ShowNegativeButton = true,
OnAction = new AsyncRelayCommand<bool>(OnUpdateDialogResult)
}));
}
catch
{
App.OpenInBrowser("https://github.com/ZuneDev/ZuneModdingHelper/releases");
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
}
}
private async Task OnUpdateDialogResult(bool accepted)
{
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
if (!accepted)
return;
ProgressDialogViewModel prog = new()
{
Title = UPDATES_DIALOG_TITLE,
Description = "Downloading update...\r\nThis may take a few minutes.",
IsIndeterminate = true,
ShowAffirmativeButton = false,
ShowNegativeButton = false,
Maximum = 1.0,
};
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(prog));
// Ask user to save file
Microsoft.Win32.SaveFileDialog saveFileDialog = new()
{
FileName = _updateInfo.Name,
InitialDirectory = new KnownFolder(KnownFolderType.Downloads).Path
};
bool dialogResult = saveFileDialog.ShowDialog() ?? false;
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
if (dialogResult)
{
_downloadedUpdatePath = saveFileDialog.FileName;
// Download new version to requested folder with progress updates
Progress<double> progress = new(p => prog.Progress = p);
prog.Progress = 0;
prog.IsIndeterminate = false;
await _updateService.DownloadUpdate(_updateInfo, _downloadedUpdatePath, progress);
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(new DialogViewModel
{
Title = UPDATES_DIALOG_TITLE,
Description = "Update downloaded. Would you like to launch the new version?",
AffirmativeText = "YES",
NegativeText = "NO",
ShowAffirmativeButton = true,
ShowNegativeButton = true,
OnAction = new AsyncRelayCommand<bool>(OnLaunchUpdateDialogResult)
}));
}
}
private async Task OnLaunchUpdateDialogResult(bool accepted)
{
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
if (!accepted)
return;
// In the future, this should launch an installer
System.Diagnostics.Process.Start("explorer", _downloadedUpdatePath);
await UpdateHelper.Instance.CheckForUpdatesAsync(true);
}
}
}
+155
View File
@@ -0,0 +1,155 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Syroot.Windows.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ZuneModdingHelper.Messages;
namespace ZuneModdingHelper.Services;
public class UpdateHelper
{
public const string UPDATES_DIALOG_TITLE = "UPDATES";
private readonly IUpdateService? _updateService = Ioc.Default.GetService<IUpdateService>();
private bool _isRunning = false;
private UpdateAvailableInfo _updateInfo;
private string _downloadedUpdatePath;
public static UpdateHelper Instance { get; } = new();
public bool Enabled => _updateService is not null;
public async Task CheckForUpdatesAsync(bool isUserTriggered)
{
if (_isRunning)
return;
_isRunning = true;
if (isUserTriggered)
{
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(new ProgressDialogViewModel
{
Title = UPDATES_DIALOG_TITLE,
Description = "Checking for updates, please wait...",
IsIndeterminate = true,
ShowAffirmativeButton = false,
}));
}
try
{
await Task.Delay(5000);
_updateInfo = await _updateService.FetchAvailableUpdate();
if (isUserTriggered)
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
if (_updateInfo is null)
{
if (isUserTriggered)
{
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(new DialogViewModel
{
Title = UPDATES_DIALOG_TITLE,
Description = "No updates available.\r\n\r\nYou're already using the latest version.",
ShowAffirmativeButton = true,
}));
}
_isRunning = false;
return;
}
// Newer version available, prompt user to download
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(new DialogViewModel
{
Title = UPDATES_DIALOG_TITLE,
Description = $"Release {_updateInfo.Name} is available. Would you like to download it now?",
AffirmativeText = "YES",
NegativeText = "NO",
ShowAffirmativeButton = true,
ShowNegativeButton = true,
OnAction = new AsyncRelayCommand<bool>(OnUpdateDialogResult)
}));
}
catch
{
if (isUserTriggered)
{
App.OpenInBrowser($"{App.RepoUri}/releases");
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
}
_isRunning = false;
}
}
private async Task OnUpdateDialogResult(bool accepted)
{
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
if (!accepted)
return;
ProgressDialogViewModel prog = new()
{
Title = UPDATES_DIALOG_TITLE,
Description = "Downloading update...\r\nThis may take a few minutes.",
IsIndeterminate = true,
ShowAffirmativeButton = false,
ShowNegativeButton = false,
Maximum = 1.0,
};
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(prog));
// Ask user to save file
Microsoft.Win32.SaveFileDialog saveFileDialog = new()
{
FileName = _updateInfo.Name,
InitialDirectory = new KnownFolder(KnownFolderType.Downloads).Path
};
bool dialogResult = saveFileDialog.ShowDialog() ?? false;
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
if (dialogResult)
{
_downloadedUpdatePath = saveFileDialog.FileName;
// Download new version to requested folder with progress updates
Progress<double> progress = new(p => prog.Progress = p);
prog.Progress = 0;
prog.IsIndeterminate = false;
await _updateService.DownloadUpdate(_updateInfo, _downloadedUpdatePath, progress);
WeakReferenceMessenger.Default.Send(new ShowDialogMessage(new DialogViewModel
{
Title = UPDATES_DIALOG_TITLE,
Description = "Update downloaded. Would you like to launch the new version?",
AffirmativeText = "YES",
NegativeText = "NO",
ShowAffirmativeButton = true,
ShowNegativeButton = true,
OnAction = new AsyncRelayCommand<bool>(OnLaunchUpdateDialogResult)
}));
}
_isRunning = false;
}
private async Task OnLaunchUpdateDialogResult(bool accepted)
{
WeakReferenceMessenger.Default.Send<CloseDialogMessage>();
if (!accepted)
return;
// In the future, this should launch an installer
System.Diagnostics.Process.Start("explorer", _downloadedUpdatePath);
}
}