PSConfigurationProcessor.cs (3544B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="PSConfigurationProcessor.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace Microsoft.WinGet.Configuration.Engine.PSObjects 8 { 9 using System; 10 using Microsoft.Management.Configuration; 11 using Microsoft.WinGet.Common.Command; 12 13 /// <summary> 14 /// Creates configuration processor and set up diagnostic logging. 15 /// If this object is the input of another cmdlet and the cmdlet is not a 16 /// long running task (aka not Continue-*) for now the caller is responsible 17 /// of updating the AsyncCommand of this object. 18 /// In the future we can implement a singleton that handles all the signaling 19 /// for main thread actions. 20 /// </summary> 21 public class PSConfigurationProcessor 22 { 23 private static readonly object CmdletLock = new (); 24 25 private PowerShellCmdlet diagnosticCommand; 26 27 /// <summary> 28 /// Initializes a new instance of the <see cref="PSConfigurationProcessor"/> class. 29 /// </summary> 30 /// <param name="factory">Processor Factory. If null, the functions (i.e. set/unit operations) may be limited.</param> 31 /// <param name="diagnosticCommand">AsyncCommand to use for diagnostics.</param> 32 /// <param name="canUseTelemetry">If telemetry can be used.</param> 33 internal PSConfigurationProcessor(IConfigurationSetProcessorFactory? factory, PowerShellCmdlet diagnosticCommand, bool canUseTelemetry) 34 { 35 this.Processor = new ConfigurationProcessor(factory); 36 this.Processor.MinimumLevel = DiagnosticLevel.Verbose; 37 this.Processor.Caller = "Microsoft.WinGet.Configuration"; 38 this.Processor.Diagnostics += (sender, args) => this.LogConfigurationDiagnostics(args); 39 this.Processor.GenerateTelemetryEvents = canUseTelemetry; 40 this.diagnosticCommand = diagnosticCommand; 41 } 42 43 /// <summary> 44 /// Gets the ConfigurationProcessor. 45 /// </summary> 46 internal ConfigurationProcessor Processor { get; private set; } 47 48 /// <summary> 49 /// Updates the cmdlet that is used for diagnostics. 50 /// </summary> 51 /// <param name="newDiagnosticCommand">New diagnostic command.</param> 52 internal void UpdateDiagnosticCmdlet(PowerShellCmdlet newDiagnosticCommand) 53 { 54 lock (CmdletLock) 55 { 56 this.diagnosticCommand = newDiagnosticCommand; 57 } 58 } 59 60 private void LogConfigurationDiagnostics(IDiagnosticInformation diagnosticInformation) 61 { 62 try 63 { 64 PowerShellCmdlet pwshCmdlet = this.diagnosticCommand; 65 if (pwshCmdlet != null) 66 { 67 // Printing each diagnostic error in their own equivalent stream is too noisy. 68 // If users want them they have to specify -Verbose. 69 string tag = $"[Diagnostic{diagnosticInformation.Level}] "; 70 pwshCmdlet.Write(StreamType.Verbose, $"{tag}{diagnosticInformation.Message}"); 71 } 72 } 73 catch (Exception) 74 { 75 // Please don't throw here. 76 } 77 } 78 } 79 }