diff --git a/src/Artemis.UI/Screens/Settings/Dialogs/UpdateDialogViewModel.cs b/src/Artemis.UI/Screens/Settings/Dialogs/UpdateDialogViewModel.cs index d5819bd9d..a048ee1f8 100644 --- a/src/Artemis.UI/Screens/Settings/Dialogs/UpdateDialogViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Dialogs/UpdateDialogViewModel.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Artemis.Core; using Artemis.UI.Services; using Artemis.UI.Shared.Services; @@ -9,12 +10,16 @@ namespace Artemis.UI.Screens.Settings.Dialogs public class UpdateDialogViewModel : DialogViewModelBase { private readonly JToken _buildInfo; + private readonly IDialogService _dialogService; private readonly IUpdateService _updateService; + private bool _canUpdate = true; - public UpdateDialogViewModel(JToken buildInfo, IUpdateService updateService) + public UpdateDialogViewModel(JToken buildInfo, IUpdateService updateService, IDialogService dialogService) { _buildInfo = buildInfo; _updateService = updateService; + _dialogService = dialogService; + CurrentBuild = Constants.BuildInfo.BuildNumberDisplay; LatestBuild = buildInfo?.SelectToken("value[0].buildNumber")?.Value(); } @@ -22,9 +27,28 @@ namespace Artemis.UI.Screens.Settings.Dialogs public string CurrentBuild { get; } public string LatestBuild { get; } + public bool CanUpdate + { + get => _canUpdate; + set => SetAndNotify(ref _canUpdate, value); + } + public async Task Update() { - await _updateService.ApplyUpdate(); + try + { + CanUpdate = false; + await _updateService.ApplyUpdate(); + } + catch (Exception e) + { + _dialogService.ShowExceptionDialog("An exception occurred while applying the update", e); + } + finally + { + CanUpdate = true; + } + Session.Close(); } } diff --git a/src/Artemis.UI/Services/UpdateService.cs b/src/Artemis.UI/Services/UpdateService.cs index f4cee099d..00ebcceba 100644 --- a/src/Artemis.UI/Services/UpdateService.cs +++ b/src/Artemis.UI/Services/UpdateService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; @@ -110,21 +111,43 @@ namespace Artemis.UI.Services public async Task ApplyUpdate() { - _logger.Information("Applying update"); + _logger.Information("ApplyUpdate: Applying update"); // Ensure the installer is up-to-date, get installer build info JToken buildInfo = await GetBuildInfo(6); + JToken finishTimeToken = buildInfo?.SelectToken("value[0].finishTime"); string installerPath = Path.Combine(Constants.ApplicationFolder, "Installer", "Artemis.Installer.exe"); // Always update installer if it is missing ^^ if (!File.Exists(installerPath)) await UpdateInstaller(); // Compare the creation date of the installer with the build date and update if needed - else if (File.GetLastWriteTime(installerPath) < buildInfo["finishTime"].Value()) - await UpdateInstaller(); + else + { + if (finishTimeToken == null) + _logger.Warning("ApplyUpdate: Failed to find build finish time at \"value[0].finishTime\", not updating the installer."); + else if (File.GetLastWriteTime(installerPath) < finishTimeToken.Value()) + await UpdateInstaller(); + } - _logger.Information("Running installer at {installerPath}", installerPath); - Process.Start(installerPath, "-autoupdate"); + _logger.Information("ApplyUpdate: Running installer at {installerPath}", installerPath); + + try + { + Process.Start(new ProcessStartInfo(installerPath, "-autoupdate") + { + UseShellExecute = true, + Verb = "runas" + }); + } + catch (Win32Exception e) + { + if (e.NativeErrorCode == 0x4c7) + _logger.Warning("ApplyUpdate: Operation was cancelled, user likely clicked No in UAC dialog."); + else + throw; + } + } private async Task UpdateInstaller()