Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
BaseCommand.cs408 linesDownload Raw Back to common
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections.Generic;6using System.Management.Automation;7using System.Management.Automation.Internal;8using System.Management.Automation.Language;9 10namespace Microsoft.PowerShell.Commands.Internal.Format11{12    /// <summary>13    /// Facade class to provide context information to process14    /// exceptions.15    /// </summary>16    internal sealed class TerminatingErrorContext17    {18        internal TerminatingErrorContext(PSCmdlet command)19        {20            if (command == null)21                throw PSTraceSource.NewArgumentNullException(nameof(command));22            _command = command;23        }24 25        [System.Diagnostics.CodeAnalysis.DoesNotReturn]26        internal void ThrowTerminatingError(ErrorRecord errorRecord)27        {28            _command.ThrowTerminatingError(errorRecord);29        }30 31        private readonly PSCmdlet _command;32    }33 34    /// <summary>35    /// Helper class to invoke a command in a secondary pipeline.36    /// NOTE: this implementation does not return any error messages37    /// that invoked pipelines might generate.38    /// </summary>39    internal sealed class CommandWrapper : IDisposable40    {41        /// <summary>42        /// Initialize the command before executing.43        /// </summary>44        /// <param name="execContext">ExecutionContext used to create sub pipeline.</param>45        /// <param name="nameOfCommand">Name of the command to run.</param>46        /// <param name="typeOfCommand">Type of the command to run.</param>47        internal void Initialize(ExecutionContext execContext, string nameOfCommand, Type typeOfCommand)48        {49            _context = execContext;50            _commandName = nameOfCommand;51            _commandType = typeOfCommand;52        }53 54        /// <summary>55        /// Add a parameter to the command invocation.56        /// It needs to be called before any execution takes place.57        /// </summary>58        /// <param name="parameterName">Name of the parameter.</param>59        /// <param name="parameterValue">Value of the parameter.</param>60        internal void AddNamedParameter(string parameterName, object parameterValue)61        {62            _commandParameterList.Add(63                CommandParameterInternal.CreateParameterWithArgument(64                    /*parameterAst*/null, parameterName, null,65                    /*argumentAst*/null, parameterValue,66                    false));67        }68 69        /// <summary>70        /// Send an object to the pipeline.71        /// </summary>72        /// <param name="o">Object to process.</param>73        /// <returns>Array of objects out of the success pipeline.</returns>74        internal Array Process(object o)75        {76            if (_pp == null)77            {78                // if this is the first call, we need to initialize the79                // pipeline underneath80                DelayedInternalInitialize();81            }82 83            return _pp.Step(o);84        }85 86        /// <summary>87        /// Shut down the pipeline.88        /// </summary>89        /// <returns>Array of objects out of the success pipeline.</returns>90        internal Array ShutDown()91        {92            if (_pp == null)93            {94                // if Process() never got called, no sub pipeline95                // ever got created, hence we just return an empty array96                return Array.Empty<object>();97            }98 99            PipelineProcessor ppTemp = _pp;100 101            _pp = null;102            return ppTemp.SynchronousExecuteEnumerate(AutomationNull.Value);103        }104 105        private void DelayedInternalInitialize()106        {107            _pp = new PipelineProcessor();108 109            CmdletInfo cmdletInfo = new CmdletInfo(_commandName, _commandType, null, null, _context);110 111            CommandProcessor cp = new CommandProcessor(cmdletInfo, _context);112 113            foreach (CommandParameterInternal par in _commandParameterList)114            {115                cp.AddParameter(par);116            }117 118            _pp.Add(cp);119        }120 121        /// <summary>122        /// Just dispose the pipeline processor.123        /// </summary>124        public void Dispose()125        {126            if (_pp == null)127                return;128 129            _pp.Dispose();130            _pp = null;131        }132 133        private PipelineProcessor _pp = null;134 135        private string _commandName = null;136        private Type _commandType;137        private readonly List<CommandParameterInternal> _commandParameterList = new List<CommandParameterInternal>();138 139        private ExecutionContext _context = null;140    }141 142    /// <summary>143    /// Base class for the command-let's we expose144    /// it contains a reference to the implementation145    /// class it wraps.146    /// </summary>147    public abstract class FrontEndCommandBase : PSCmdlet, IDisposable148    {149        #region Command Line Switches150        /// <summary>151        /// This parameter specifies the current pipeline object.152        /// </summary>153        [Parameter(ValueFromPipeline = true)]154        public PSObject InputObject { get; set; } = AutomationNull.Value;155 156        #endregion157 158        /// <summary>159        /// Hook up the calls from the implementation object160        /// and then call the implementation's Begin()161        /// </summary>162        protected override void BeginProcessing()163        {164            Diagnostics.Assert(this.implementation != null, "this.implementation is null");165            this.implementation.OuterCmdletCall = new ImplementationCommandBase.OuterCmdletCallback(this.OuterCmdletCall);166            this.implementation.InputObjectCall = new ImplementationCommandBase.InputObjectCallback(this.InputObjectCall);167            this.implementation.WriteObjectCall = new ImplementationCommandBase.WriteObjectCallback(this.WriteObjectCall);168 169            this.implementation.CreateTerminatingErrorContext();170 171            implementation.BeginProcessing();172        }173 174        /// <summary>175        /// Call the implementation.176        /// </summary>177        protected override void ProcessRecord()178        {179            implementation.ProcessRecord();180        }181 182        /// <summary>183        /// Call the implementation.184        /// </summary>185        protected override void EndProcessing()186        {187            implementation.EndProcessing();188        }189 190        /// <summary>191        /// Call the implementation.192        /// </summary>193        protected override void StopProcessing()194        {195            implementation.StopProcessing();196        }197 198        /// <summary>199        /// Callback for the implementation to obtain a reference to the Cmdlet object.200        /// </summary>201        /// <returns>Cmdlet reference.</returns>202        protected virtual PSCmdlet OuterCmdletCall()203        {204            return this;205        }206 207        /// <summary>208        /// Callback for the implementation to get the current pipeline object.209        /// </summary>210        /// <returns>Current object from the pipeline.</returns>211        protected virtual PSObject InputObjectCall()212        {213            // just bind to the input object parameter214            return this.InputObject;215        }216 217        /// <summary>218        /// Callback for the implementation to write objects.219        /// </summary>220        /// <param name="value">Object to be written.</param>221        protected virtual void WriteObjectCall(object value)222        {223            // just call Monad API224            this.WriteObject(value);225        }226 227        /// <summary>228        /// Reference to the implementation command that this class229        /// is wrapping.230        /// </summary>231        internal ImplementationCommandBase implementation = null;232 233        #region IDisposable Implementation234 235        /// <summary>236        /// Default implementation just delegates to internal helper.237        /// </summary>238        /// <remarks>This method calls GC.SuppressFinalize</remarks>239        public void Dispose()240        {241            Dispose(true);242 243            GC.SuppressFinalize(this);244        }245 246        /// <summary>247        /// Dispose pattern implementation.248        /// </summary>249        /// <param name="disposing"></param>250        protected virtual void Dispose(bool disposing)251        {252            if (disposing)253            {254                InternalDispose();255            }256        }257 258        /// <summary>259        /// Do-nothing implementation: derived classes will override as see fit.260        /// </summary>261        protected virtual void InternalDispose()262        {263            if (this.implementation == null)264                return;265 266            this.implementation.Dispose();267            this.implementation = null;268        }269        #endregion270    }271 272    /// <summary>273    /// Implementation class to be called by the outer command274    /// In order to properly work, the callbacks have to be properly set by the outer command.275    /// </summary>276    internal class ImplementationCommandBase : IDisposable277    {278        /// <summary>279        /// Inner version of CommandBase.BeginProcessing()280        /// </summary>281        internal virtual void BeginProcessing()282        {283        }284 285        /// <summary>286        /// Inner version of CommandBase.ProcessRecord()287        /// </summary>288        internal virtual void ProcessRecord()289        {290        }291 292        /// <summary>293        /// Inner version of CommandBase.EndProcessing()294        /// </summary>295        internal virtual void EndProcessing()296        {297        }298 299        /// <summary>300        /// Inner version of CommandBase.StopProcessing()301        /// </summary>302        internal virtual void StopProcessing()303        {304        }305 306        /// <summary>307        /// Retrieve the current input pipeline object.308        /// </summary>309        internal virtual PSObject ReadObject()310        {311            // delegate to the front end object312            System.Diagnostics.Debug.Assert(this.InputObjectCall != null, "this.InputObjectCall is null");313            return this.InputObjectCall();314        }315 316        /// <summary>317        /// Write an object to the pipeline.318        /// </summary>319        /// <param name="o">Object to write to the pipeline.</param>320        internal virtual void WriteObject(object o)321        {322            // delegate to the front end object323            System.Diagnostics.Debug.Assert(this.WriteObjectCall != null, "this.WriteObjectCall is null");324            this.WriteObjectCall(o);325        }326 327        // callback methods to get to the outer Monad Cmdlet328        /// <summary>329        /// Get a hold of the Monad outer Cmdlet.330        /// </summary>331        /// <returns></returns>332        internal virtual PSCmdlet OuterCmdlet()333        {334            // delegate to the front end object335            System.Diagnostics.Debug.Assert(this.OuterCmdletCall != null, "this.OuterCmdletCall is null");336            return this.OuterCmdletCall();337        }338 339        protected TerminatingErrorContext TerminatingErrorContext { get; private set; }340 341        internal void CreateTerminatingErrorContext()342        {343            TerminatingErrorContext = new TerminatingErrorContext(this.OuterCmdlet());344        }345 346        /// <summary>347        /// Delegate definition to get to the outer command-let.348        /// </summary>349        internal delegate PSCmdlet OuterCmdletCallback();350 351        /// <summary>352        /// Callback to get to the outer command-let.353        /// </summary>354        internal OuterCmdletCallback OuterCmdletCall;355 356        // callback to the methods to get an object and write an object357        /// <summary>358        /// Delegate definition to get to the current pipeline input object.359        /// </summary>360        internal delegate PSObject InputObjectCallback();361 362        /// <summary>363        /// Delegate definition to write object.364        /// </summary>365        internal delegate void WriteObjectCallback(object o);366 367        /// <summary>368        /// Callback to read object.369        /// </summary>370        internal InputObjectCallback InputObjectCall;371 372        /// <summary>373        /// Callback to write object.374        /// </summary>375        internal WriteObjectCallback WriteObjectCall;376 377        #region IDisposable Implementation378 379        /// <summary>380        /// Default implementation just delegates to internal helper.381        /// </summary>382        /// <remarks>This method calls GC.SuppressFinalize</remarks>383        public void Dispose()384        {385            Dispose(true);386 387            GC.SuppressFinalize(this);388        }389 390        private void Dispose(bool disposing)391        {392            if (disposing)393            {394                InternalDispose();395            }396        }397 398        /// <summary>399        /// Do-nothing implementation: derived classes will override as see fit.400        /// </summary>401        protected virtual void InternalDispose()402        {403        }404        #endregion405 406    }407}408