winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

RepairPackageCommand.cs (6273B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="RepairPackageCommand.cs" company="Microsoft Corporation">
      3 //     Copyright (c) Microsoft Corporation. Licensed under the MIT License.
      4 // </copyright>
      5 // -----------------------------------------------------------------------------
      6 
      7 namespace Microsoft.WinGet.Client.Engine.Commands
      8 {
      9     using System;
     10     using System.Management.Automation;
     11     using System.Threading.Tasks;
     12     using Microsoft.Management.Deployment;
     13     using Microsoft.WinGet.Client.Engine.Commands.Common;
     14     using Microsoft.WinGet.Client.Engine.Exceptions;
     15     using Microsoft.WinGet.Client.Engine.Helpers;
     16     using Microsoft.WinGet.Client.Engine.PSObjects;
     17     using Microsoft.WinGet.Resources;
     18 
     19     /// <summary>
     20     /// This class defines the repair package command.
     21     /// </summary>
     22     public sealed class RepairPackageCommand : PackageCommand
     23     {
     24         /// <summary>
     25         /// Initializes a new instance of the <see cref="RepairPackageCommand"/> class.
     26         /// </summary>
     27         /// <param name="psCmdlet">Caller cmdlet.</param>
     28         /// <param name="psCatalogPackage">PSCatalogPackage.</param>
     29         /// <param name="allowHashMismatch">To skip the installer hash validation check.</param>
     30         /// <param name="force">To continue upon non security related failures.</param>
     31         /// <param name="version">Version to repair.</param>
     32         /// <param name="log">Logging file location.</param>
     33         /// <param name="id">Package identifier.</param>
     34         /// <param name="name">Name of package.</param>
     35         /// <param name="moniker">Moniker of package.</param>
     36         /// <param name="source">Source to search. if null, all are searched.</param>
     37         /// <param name="query">Match against any field of a package.</param>
     38         public RepairPackageCommand(
     39             PSCmdlet psCmdlet,
     40             bool allowHashMismatch,
     41             bool force,
     42             PSCatalogPackage psCatalogPackage,
     43             string version,
     44             string log,
     45             string id,
     46             string name,
     47             string moniker,
     48             string source,
     49             string[] query)
     50             : base(psCmdlet)
     51         {
     52             this.Force = force;
     53             this.AllowHashMismatch = allowHashMismatch;
     54 
     55             if (psCatalogPackage != null)
     56             {
     57                 this.CatalogPackage = psCatalogPackage;
     58             }
     59 
     60             this.Version = version;
     61 
     62             this.Id = id;
     63             this.Name = name;
     64             this.Moniker = moniker;
     65             this.Source = source;
     66             this.Query = query;
     67 
     68             this.Log = log;
     69         }
     70 
     71         /// <summary>
     72         /// Gets or sets the path to the logging file.
     73         /// </summary>
     74         private string? Log { get; set; }
     75 
     76         /// <summary>
     77         /// Gets or sets a value indicating whether to continue upon non security related failures.
     78         /// </summary>
     79         private bool Force { get; set; }
     80 
     81         /// <summary>
     82         /// Gets or sets a value indicating whether to skip the installer hash validation check.
     83         /// </summary>
     84         private bool AllowHashMismatch { get; set; }
     85 
     86         /// <summary>
     87         /// Process repair package.
     88         /// </summary>
     89         /// <param name="psPackageFieldMatchOption">PSPackageFieldMatchOption.</param>
     90         /// <param name="psPackageRepairMode">PSPackageRepairMode.</param>
     91         public void Repair(
     92             string psPackageFieldMatchOption,
     93             string psPackageRepairMode)
     94         {
     95             var result = this.Execute(
     96                 async () => await this.GetPackageAndExecuteAsync(
     97                     CompositeSearchBehavior.AllCatalogs,
     98                     PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption),
     99                     async (package, version) =>
    100                     {
    101                         var repairOptions = this.GetRepairOptions(version, PSEnumHelpers.ToPackageRepairMode(psPackageRepairMode));
    102                         return await this.RepairPackageAsync(package, repairOptions);
    103                     }));
    104 
    105             if (result != null)
    106             {
    107                 if (result.Item1.Status == RepairResultStatus.RepairError
    108                     && result.Item1.ExtendedErrorCode != null)
    109                 {
    110                     if (result.Item1.ExtendedErrorCode.InnerException != null)
    111                     {
    112                         throw new WinGetRepairPackageException(result.Item1.ExtendedErrorCode.HResult, result.Item1.RepairerErrorCode, result.Item1.ExtendedErrorCode.InnerException);
    113                     }
    114 
    115                     throw new WinGetRepairPackageException(result.Item1.ExtendedErrorCode.HResult, result.Item1.RepairerErrorCode);
    116                 }
    117 
    118                 this.Write(WinGet.Common.Command.StreamType.Object, new PSRepairResult(result.Item1, result.Item2));
    119             }
    120         }
    121 
    122         private RepairOptions GetRepairOptions(
    123             PackageVersionId? version,
    124             PackageRepairMode repairMode)
    125         {
    126             var options = ManagementDeploymentFactory.Instance.CreateRepairOptions();
    127             options.AllowHashMismatch = this.AllowHashMismatch;
    128             options.Force = this.Force;
    129 
    130             if (this.Log != null)
    131             {
    132                 options.LogOutputPath = this.Log;
    133             }
    134 
    135             options.PackageRepairMode = repairMode;
    136 
    137             if (version != null)
    138             {
    139                 options.PackageVersionId = version;
    140             }
    141 
    142             return options;
    143         }
    144 
    145         private async Task<RepairResult> RepairPackageAsync(
    146             CatalogPackage catalogPackage,
    147             RepairOptions repairOptions)
    148         {
    149             var progressOperation = new RepairOperationWithProgress(
    150                 this,
    151                 string.Format(Resources.ProgressRecordActivityRepairing, catalogPackage.Name));
    152 
    153             return await progressOperation.ExecuteAsync(
    154                 () => PackageManagerWrapper.Instance.RepairPackageAsync(catalogPackage, repairOptions));
    155         }
    156     }
    157 }