protected static void CancelledInformation(UpdateInformation updateInformation, bool userNotification = false)
 {
     Logger.Debug("Operation was cancelled by user request");
     updateInformation.Result  = UpdateResult.Cancelled;
     updateInformation.Message = "Operation cancelled by user request";
     updateInformation.RequiresUserNotification = userNotification;
 }
 protected static void ErrorInformation(UpdateInformation updateInformation, string errorMessage, bool userNotification = true)
 {
     Logger.Debug($"Update failed with message: {errorMessage}");
     updateInformation.Result  = UpdateResult.Failed;
     updateInformation.Message = errorMessage;
     updateInformation.RequiresUserNotification = userNotification;
 }
 protected static void SuccessInformation(UpdateInformation updateInformation, string message, bool requiresRestart = false, bool userNotification = true)
 {
     Logger.Debug("Update was completed sucessfully");
     updateInformation.Result  = requiresRestart ? UpdateResult.SuccessRestartRequired : UpdateResult.Success;
     updateInformation.Message = message;
     updateInformation.RequiresUserNotification = userNotification;
 }
 protected static void NoUpdateInformation(UpdateInformation updateInformation, bool userNotification = false)
 {
     Logger.Debug("No update was required");
     updateInformation.Result  = UpdateResult.NoUpdate;
     updateInformation.Message = "No update was required";
     updateInformation.RequiresUserNotification = userNotification;
 }
        private void HandleElevationRequest(ElevationRequireException e, UpdateInformation updateInformation)
        {
            var restoreBackup = true;

            try
            {
                if (Elevator.IsProcessElevated)
                {
                    throw new UpdaterException("The process is already elevated", e);
                }

                var lockedResult = HandleLockedComponentsAsync(true, out var pendingComponents).Result;
                switch (lockedResult.Status)
                {
                case HandlePendingComponentsStatus.Declined:
                    ErrorInformation(updateInformation, lockedResult.Message);
                    return;
                }

                if (!PermitElevationRequest())
                {
                    ErrorInformation(updateInformation, "The update was stopped because the process needs to be elevated");
                    return;
                }

                try
                {
                    var allComponents = CreateRestartOptions(e.AggregateComponents().Union(pendingComponents).Distinct().ToList());
                    Elevator.RestartElevated(allComponents);
                    restoreBackup = false;
                }
                catch (Exception ex)
                {
                    if (!(ex is Win32Exception && ex.HResult == -2147467259))
                    {
                        throw;
                    }
                    // The elevation was not accepted by the user
                    CancelledInformation(updateInformation);
                }
            }
            finally
            {
                if (restoreBackup)
                {
                    RestoreBackup();
                }
            }
        }
        public virtual async Task <UpdateInformation> CheckAndPerformUpdateAsync(CancellationToken cancellation)
        {
            cancellation.ThrowIfCancellationRequested();
            Logger.Info("Start automatic check and update...");
            var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellation);

            var updateInformation = new UpdateInformation();
            var finalCleanUp      = true;

            try
            {
                try
                {
                    var stream = await GetMetadataStreamAsync(cts.Token);

                    cts.Token.ThrowIfCancellationRequested();

                    if (stream is null || stream.Length == 0)
                    {
                        throw new UpdaterException($"Unable to get the update metadata from: {UpdateCatalogLocation}");
                    }
                    if (!await ValidateCatalogStreamAsync(stream))
                    {
                        throw new UpdaterException("Stream validation for metadata failed. Download corrupted?");
                    }

                    try
                    {
                        var components = await GetCatalogComponentsAsync(stream, cts.Token);

                        if (components is null)
                        {
                            NoUpdateInformation(updateInformation);
                            return(updateInformation);
                        }
                        _components.AddRange(components);
                    }
                    catch (Exception e)
                    {
                        Logger.Error($"Failed processing catalog: {e.Message}");
                        throw;
                    }

                    await CalculateComponentStatusAsync(cts.Token);
                    await CalculateRemovableComponentsAsync();

                    cts.Token.ThrowIfCancellationRequested();

                    if (!RemovableComponents.Any() && (!Components.Any() || Components.All(x => x.RequiredAction == ComponentAction.Keep)))
                    {
                        NoUpdateInformation(updateInformation);
                        return(updateInformation);
                    }

                    await UpdateAsync(cts.Token);

                    var pendingResult = await HandleLockedComponentsAsync(false, out var pc, cts.Token);

                    switch (pendingResult.Status)
                    {
                    case HandlePendingComponentsStatus.HandledButStillPending:
                    case HandlePendingComponentsStatus.Declined:
                        throw new RestartDeniedOrFailedException(pendingResult.Message);

                    case HandlePendingComponentsStatus.Restart:
                        finalCleanUp = false;
                        Restart(pc.ToList());
                        break;

                    default:
                        SuccessInformation(updateInformation, "Success");
                        break;
                    }
                }
                catch (Exception e)
                {
                    var throwFlag = false;
                    if (e.IsExceptionType <OperationCanceledException>())
                    {
                        CancelledInformation(updateInformation);
                    }
                    else if (e is AggregateException && e.IsExceptionType <UpdaterException>())
                    {
                        ErrorInformation(updateInformation, e.TryGetWrappedException()?.Message);
                    }
                    else if (e is UpdaterException)
                    {
                        ErrorInformation(updateInformation, e.Message);
                    }
                    else if (e.IsExceptionType <ElevationRequireException>())
                    {
                        throw;
                    }
                    else
                    {
                        throwFlag = true;
                    }

                    RestoreBackup();

                    if (throwFlag)
                    {
                        throw;
                    }
                }
            }
            catch (RestoreFailedException e)
            {
                OnRestoreFailed(e, updateInformation);
            }
            catch (ElevationRequireException e)
            {
                HandleElevationRequest(e, updateInformation);
            }
            finally
            {
                if (finalCleanUp)
                {
                    await Clean();
                }
            }

            return(updateInformation);
        }
 protected virtual void OnRestoreFailed(Exception ex, UpdateInformation updateInformation)
 {
     ErrorInformation(updateInformation, ex.Message);
 }