WingetCLIWrapper.cs (3847B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="WingetCLIWrapper.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace Microsoft.WinGet.Client.Engine.Helpers 8 { 9 using System; 10 using System.Diagnostics; 11 using System.IO; 12 using Microsoft.WinGet.Client.Engine.Common; 13 using Microsoft.WinGet.Client.Engine.Exceptions; 14 using Microsoft.WinGet.Common.Command; 15 16 /// <summary> 17 /// Calls winget directly. 18 /// </summary> 19 internal class WingetCLIWrapper 20 { 21 /// <summary> 22 /// The file name to use in start info. 23 /// </summary> 24 private readonly string wingetPath; 25 26 /// <summary> 27 /// Initializes a new instance of the <see cref="WingetCLIWrapper"/> class. 28 /// When app execution alias is disabled the path of the exe is 29 /// in the package family name directory in the local app data windows app directory. If its enabled then there's 30 /// link in the windows app data directory. To avoid checking if its enabled or not, just look in the package 31 /// family name directory. 32 /// For test, point to the wingetdev executable. 33 /// </summary> 34 /// <param name="fullPath">Use full path or not.</param> 35 public WingetCLIWrapper(bool fullPath = true) 36 { 37 if (Utilities.ExecutingAsSystem) 38 { 39 throw new NotSupportedException(); 40 } 41 42 if (fullPath) 43 { 44 this.wingetPath = WinGetFullPath; 45 } 46 else 47 { 48 this.wingetPath = Constants.WinGetExe; 49 } 50 } 51 52 /// <summary> 53 /// Gets the full path of winget executable. 54 /// </summary> 55 public static string WinGetFullPath 56 { 57 get 58 { 59 return Path.Combine( 60 Utilities.LocalDataWindowsAppPath, 61 Constants.WingetPackageFamilyName, 62 Constants.WinGetExe); 63 } 64 } 65 66 /// <summary> 67 /// Runs winget command with parameters. 68 /// </summary> 69 /// <param name="pwshCmdlet">PowerShell cmdlet.</param> 70 /// <param name="command">Command.</param> 71 /// <param name="parameters">Parameters.</param> 72 /// <param name="timeOut">Time out.</param> 73 /// <returns>WinGetCommandResult.</returns> 74 public WinGetCLICommandResult RunCommand(PowerShellCmdlet pwshCmdlet, string command, string? parameters = null, int timeOut = 60000) 75 { 76 string args = command; 77 if (!string.IsNullOrEmpty(parameters)) 78 { 79 args += ' ' + parameters; 80 } 81 82 pwshCmdlet.Write(StreamType.Verbose, $"Running {this.wingetPath} with {args}"); 83 84 Process p = new () 85 { 86 StartInfo = new (this.wingetPath, args) 87 { 88 UseShellExecute = false, 89 RedirectStandardOutput = true, 90 RedirectStandardError = true, 91 }, 92 }; 93 94 p.Start(); 95 96 if (p.WaitForExit(timeOut)) 97 { 98 return new WinGetCLICommandResult( 99 command, 100 parameters, 101 p.ExitCode, 102 p.StandardOutput.ReadToEnd(), 103 p.StandardError.ReadToEnd()); 104 } 105 106 throw new WinGetCLITimeoutException(command, parameters); 107 } 108 } 109 }