ManagementDeploymentCommand.cs (3902B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="ManagementDeploymentCommand.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.Common 8 { 9 using System; 10 using System.Collections.Generic; 11 using System.Management.Automation; 12 using System.Threading.Tasks; 13 using Microsoft.Management.Deployment; 14 using Microsoft.WinGet.Client.Engine.Common; 15 using Microsoft.WinGet.Client.Engine.Exceptions; 16 using Microsoft.WinGet.Client.Engine.Helpers; 17 18 /// <summary> 19 /// This is the base class for all of the commands in this module that use the COM APIs. 20 /// </summary> 21 public abstract class ManagementDeploymentCommand : BaseCommand 22 { 23 static ManagementDeploymentCommand() 24 { 25 WinRTHelpers.Initialize(); 26 } 27 28 /// <summary> 29 /// Initializes a new instance of the <see cref="ManagementDeploymentCommand"/> class. 30 /// </summary> 31 /// <param name="psCmdlet">psCmdlet.</param> 32 internal ManagementDeploymentCommand(PSCmdlet psCmdlet) 33 : base(psCmdlet) 34 { 35 #if POWERSHELL_WINDOWS 36 if (Utilities.UsesInProcWinget) 37 { 38 throw new WindowsPowerShellNotSupported(); 39 } 40 #endif 41 } 42 43 /// <summary> 44 /// Retrieves the specified source or all sources if <paramref name="source" /> is null. 45 /// </summary> 46 /// <returns>A list of <see cref="PackageCatalogReference" /> instances.</returns> 47 /// <param name="source">The name of the source to retrieve. If null, then all sources are returned.</param> 48 /// <exception cref="ArgumentException">The source does not exist.</exception> 49 internal IReadOnlyList<PackageCatalogReference> GetPackageCatalogReferences(string? source) 50 { 51 if (string.IsNullOrEmpty(source)) 52 { 53 return PackageManagerWrapper.Instance.GetPackageCatalogs(); 54 } 55 else 56 { 57 return new List<PackageCatalogReference>() 58 { 59 PackageManagerWrapper.Instance.GetPackageCatalogByName(source!) 60 ?? throw new InvalidSourceException(source!), 61 }; 62 } 63 } 64 65 /// <summary> 66 /// Executes the cmdlet. All cmdlets that uses the COM APIs and don't call async functions MUST use this method. 67 /// The inproc COM API may deadlock on an STA thread. 68 /// </summary> 69 /// <typeparam name="TResult">The type of result of the cmdlet.</typeparam> 70 /// <param name="func">Cmdlet function.</param> 71 /// <returns>The result of the cmdlet.</returns> 72 protected TResult Execute<TResult>(Func<TResult> func) 73 { 74 if (Utilities.UsesInProcWinget) 75 { 76 return this.RunOnMTA(func); 77 } 78 79 return func(); 80 } 81 82 /// <summary> 83 /// Executes the cmdlet in a different thread and waits for results. 84 /// </summary> 85 /// <typeparam name="TResult">The type of result of the cmdlet.</typeparam> 86 /// <param name="func">Cmdlet function.</param> 87 /// <returns>The result of the cmdlet.</returns> 88 protected TResult Execute<TResult>(Func<Task<TResult>> func) 89 { 90 var runningTask = this.RunOnMTA( 91 async () => 92 { 93 return await func(); 94 }); 95 96 this.Wait(runningTask); 97 return runningTask.Result; 98 } 99 } 100 }