/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/System.Management.Automation/namespaces/CoreCommandContext.cs
1 148 строк
39 KB
xtqqczze
Remove redundant `Attribute` suffix (#24940)
07 фев 2025, 20:18
Не верифицирован
07 фев 2025, 20:18
1790f3a
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Collections.ObjectModel; using Dbg = System.Management.Automation; namespace System.Management.Automation { /// <summary> /// The context of the core command that is being run. This /// includes data like the user name and password, as well /// as callbacks for streaming output, prompting, and progress. /// /// This allows the providers to be called in a variety of situations. /// The most common will be from the core cmdlets themselves but they /// can also be called programmatically either by having the results /// accumulated or by providing delegates for the various streams. /// /// NOTE: USER Feedback mechanism are only enabled for the CoreCmdlet /// case. This is because we have not seen a use-case for them in the /// other scenarios. /// </summary> internal sealed class CmdletProviderContext { #region Trace object /// <summary> /// An instance of the PSTraceSource class used for trace output /// using "CmdletProviderContext" as the category. /// </summary> [Dbg.TraceSource( "CmdletProviderContext", "The context under which a core command is being run.")] private static readonly Dbg.PSTraceSource s_tracer = Dbg.PSTraceSource.GetTracer("CmdletProviderContext", "The context under which a core command is being run."); #endregion Trace object #region Constructor /// <summary> /// Constructs the context under which the core command providers /// operate. /// </summary> /// <param name="executionContext"> /// The context of the engine. /// </param> /// <exception cref="ArgumentNullException"> /// If <paramref name="executionContext"/> is null. /// </exception> internal CmdletProviderContext(ExecutionContext executionContext) { if (executionContext == null) { throw PSTraceSource.NewArgumentNullException(nameof(executionContext)); } ExecutionContext = executionContext; Origin = CommandOrigin.Internal; Drive = executionContext.EngineSessionState.CurrentDrive; if ((executionContext.CurrentCommandProcessor != null) && (executionContext.CurrentCommandProcessor.Command is Cmdlet)) { _command = (Cmdlet)executionContext.CurrentCommandProcessor.Command; } } /// <summary> /// Constructs the context under which the core command providers /// operate. /// </summary> /// <param name="executionContext"> /// The context of the engine. /// </param> /// <param name="origin"> /// The origin of the caller of this API /// </param> /// <exception cref="ArgumentNullException"> /// If <paramref name="executionContext"/> is null. /// </exception> internal CmdletProviderContext(ExecutionContext executionContext, CommandOrigin origin) { if (executionContext == null) { throw PSTraceSource.NewArgumentNullException(nameof(executionContext)); } ExecutionContext = executionContext; Origin = origin; } /// <summary> /// Constructs the context under which the core command providers /// operate. /// </summary> /// <param name="command"> /// The command object that is running. /// </param> /// <param name="credentials"> /// The credentials the core command provider should use. /// </param> /// <param name="drive"> /// The drive under which this context should operate. /// </param> /// <exception cref="ArgumentNullException"> /// If <paramref name="command"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// If <paramref name="command"/> contains a null Host or Context reference. /// </exception> internal CmdletProviderContext( PSCmdlet command, PSCredential credentials, PSDriveInfo drive) { // verify the command parameter if (command == null) { throw PSTraceSource.NewArgumentNullException(nameof(command)); } _command = command; Origin = command.CommandOrigin; if (credentials != null) { _credentials = credentials; } Drive = drive; if (command.Host == null) { throw PSTraceSource.NewArgumentException("command.Host"); } if (command.Context == null) { throw PSTraceSource.NewArgumentException("command.Context"); } ExecutionContext = command.Context; // Stream will default to true because command methods will be used. PassThru = true; _streamErrors = true; } /// <summary> /// Constructs the context under which the core command providers /// operate. /// </summary> /// <param name="command"> /// The command object that is running. /// </param> /// <param name="credentials"> /// The credentials the core command provider should use. /// </param> /// <exception cref="ArgumentNullException"> /// If <paramref name="command"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// If <paramref name="command"/> contains a null Host or Context reference. /// </exception> internal CmdletProviderContext( PSCmdlet command, PSCredential credentials) { // verify the command parameter if (command == null) { throw PSTraceSource.NewArgumentNullException(nameof(command)); } _command = command; Origin = command.CommandOrigin; if (credentials != null) { _credentials = credentials; } if (command.Host == null) { throw PSTraceSource.NewArgumentException("command.Host"); } if (command.Context == null) { throw PSTraceSource.NewArgumentException("command.Context"); } ExecutionContext = command.Context; // Stream will default to true because command methods will be used. PassThru = true; _streamErrors = true; } /// <summary> /// Constructs the context under which the core command providers /// operate. /// </summary> /// <param name="command"> /// The command object that is running. /// </param> /// <exception cref="ArgumentNullException"> /// If <paramref name="command"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// If <paramref name="command"/> contains a null Host or Context reference. /// </exception> internal CmdletProviderContext( Cmdlet command) { // verify the command parameter if (command == null) { throw PSTraceSource.NewArgumentNullException(nameof(command)); } _command = command; Origin = command.CommandOrigin; if (command.Context == null) { throw PSTraceSource.NewArgumentException("command.Context"); } ExecutionContext = command.Context; // Stream will default to true because command methods will be used. PassThru = true; _streamErrors = true; } /// <summary> /// Constructs the context under which the core command providers /// operate using an existing context. /// </summary> /// <param name="contextToCopyFrom"> /// A CmdletProviderContext instance to copy the filters, ExecutionContext, /// Credentials, Drive, and Force options from. /// </param> /// <exception cref="ArgumentNullException"> /// If <paramref name="contextToCopyFrom"/> is null. /// </exception> internal CmdletProviderContext( CmdletProviderContext contextToCopyFrom) { if (contextToCopyFrom == null) { throw PSTraceSource.NewArgumentNullException(nameof(contextToCopyFrom)); } ExecutionContext = contextToCopyFrom.ExecutionContext; _command = contextToCopyFrom._command; if (contextToCopyFrom.Credential != null) { _credentials = contextToCopyFrom.Credential; } Drive = contextToCopyFrom.Drive; _force = contextToCopyFrom.Force; this.CopyFilters(contextToCopyFrom); SuppressWildcardExpansion = contextToCopyFrom.SuppressWildcardExpansion; DynamicParameters = contextToCopyFrom.DynamicParameters; Origin = contextToCopyFrom.Origin; // Copy the stopping state incase the source context // has already been signaled for stopping Stopping = contextToCopyFrom.Stopping; // add this context to the stop referral on the copied // context contextToCopyFrom.StopReferrals.Add(this); _copiedContext = contextToCopyFrom; } #endregion Constructor #region private properties /// <summary> /// If the constructor that takes a context to copy is /// called, this will be set to the context being copied. /// </summary> private readonly CmdletProviderContext _copiedContext; /// <summary> /// The credentials under which the operation should run. /// </summary> private readonly PSCredential _credentials = PSCredential.Empty; /// <summary> /// The force parameter gives guidance to providers on how vigorously they /// should try to perform an operation. /// </summary> private bool _force; /// <summary> /// The command which defines the context. This should not be /// made visible to anyone and should only be set through the /// constructor. /// </summary> private readonly Cmdlet _command; /// <summary> /// This makes the origin of the provider request visible to the internals. /// </summary> internal CommandOrigin Origin { get; } = CommandOrigin.Internal; /// <summary> /// This defines the default behavior for the WriteError method. /// If it is true, a call to this method will result in an immediate call /// to the command WriteError method, or to the writeErrorDelegate if /// one has been supplied. /// If it is false, the objects will be accumulated until the /// GetErrorObjects method is called. /// </summary> private readonly bool _streamErrors; /// <summary> /// A collection in which objects that are written using the WriteObject(s) /// methods are accumulated if <see cref="PassThru"/> is false. /// </summary> private Collection<PSObject> _accumulatedObjects = new Collection<PSObject>(); /// <summary> /// A collection in which objects that are written using the WriteError /// method are accumulated if <see cref="PassThru"/> is false. /// </summary> private Collection<ErrorRecord> _accumulatedErrorObjects = new Collection<ErrorRecord>(); /// <summary> /// The instance of the provider that is currently executing in this context. /// </summary> private System.Management.Automation.Provider.CmdletProvider _providerInstance; #endregion private properties #region Internal properties /// <summary> /// Gets the execution context of the engine. /// </summary> internal ExecutionContext ExecutionContext { get; } /// <summary> /// Gets or sets the provider instance for the current /// execution context. /// </summary> internal System.Management.Automation.Provider.CmdletProvider ProviderInstance { get { return _providerInstance; } set { _providerInstance = value; } } /// <summary> /// Copies the include, exclude, and provider filters from /// the specified context to this context. /// </summary> /// <param name="context"> /// The context to copy the filters from. /// </param> private void CopyFilters(CmdletProviderContext context) { Dbg.Diagnostics.Assert( context != null, "The caller should have verified the context"); Include = context.Include; Exclude = context.Exclude; Filter = context.Filter; } internal void RemoveStopReferral() => _copiedContext?.StopReferrals.Remove(this); #endregion Internal properties #region Public properties /// <summary> /// Gets or sets the dynamic parameters for the context. /// </summary> internal object DynamicParameters { get; set; } /// <summary> /// Returns MyInvocation from the underlying cmdlet. /// </summary> internal InvocationInfo MyInvocation { get { if (_command != null) { return _command.MyInvocation; } else { return null; } } } /// <summary> /// Determines if the Write* calls should be passed through to the command /// instance if there is one. The default value is true. /// </summary> internal bool PassThru { get; set; } /// <summary> /// The drive associated with this context. /// </summary> /// <exception cref="ArgumentNullException"> /// If <paramref name="value"/> is null on set. /// </exception> internal PSDriveInfo Drive { get; set; } /// <summary> /// Gets the user name under which the operation should run. /// </summary> internal PSCredential Credential { get { PSCredential result = _credentials; // If the username wasn't specified, use the drive credentials if (_credentials == null && Drive != null) { result = Drive.Credential; } return result; } } #region Transaction Support /// <summary> /// Gets the flag that determines if the command requested a transaction. /// </summary> internal bool UseTransaction { get { if ((_command != null) && (_command.CommandRuntime != null)) { MshCommandRuntime mshRuntime = _command.CommandRuntime as MshCommandRuntime; if (mshRuntime != null) { return mshRuntime.UseTransaction; } } return false; } } /// <summary> /// Returns true if a transaction is available and active. /// </summary> public bool TransactionAvailable() { if (_command != null) { return _command.TransactionAvailable(); } return false; } /// <summary> /// Gets an object that surfaces the current PowerShell transaction. /// When this object is disposed, PowerShell resets the active transaction. /// </summary> public PSTransactionContext CurrentPSTransaction { get { if (_command != null) { return _command.CurrentPSTransaction; } return null; } } #endregion Transaction Support /// <summary> /// Gets or sets the Force property that is passed to providers. /// </summary> internal SwitchParameter Force { get { return _force; } set { _force = value; } } /// <summary> /// The provider specific filter that should be used when determining /// which items an action should take place on. /// </summary> internal string Filter { get; set; } /// <summary> /// A glob string that signifies which items should be included when determining /// which items the action should occur on. /// </summary> internal Collection<string> Include { get; private set; } /// <summary> /// A glob string that signifies which items should be excluded when determining /// which items the action should occur on. /// </summary> internal Collection<string> Exclude { get; private set; } /// <summary> /// Gets or sets the property that tells providers (that /// declare their own wildcard support) to suppress wildcard /// expansion. This is set when the user specifies the /// -LiteralPath parameter to one of the core commands. /// </summary> public bool SuppressWildcardExpansion { get; internal set; } #region User feedback mechanisms /// <summary> /// Confirm the operation with the user. /// </summary> /// <param name="target"> /// Name of the target resource being acted upon /// </param> /// <remarks>true if-and-only-if the action should be performed</remarks> /// <exception cref="PipelineStoppedException"> /// The ActionPreference.Stop or ActionPreference.Inquire policy /// triggered a terminating error. The pipeline failure will be /// ActionPreferenceStopException. /// Also, this occurs if the pipeline was already stopped. /// </exception> internal bool ShouldProcess( string target) { bool result = true; if (_command != null) { result = _command.ShouldProcess(target); } return result; } /// <summary> /// Confirm the operation with the user. /// </summary> /// <param name="target"> /// Name of the target resource being acted upon /// </param> /// <param name="action">What action was being performed.</param> /// <remarks>true if-and-only-if the action should be performed</remarks> /// <exception cref="PipelineStoppedException"> /// The ActionPreference.Stop or ActionPreference.Inquire policy /// triggered a terminating error. The pipeline failure will be /// ActionPreferenceStopException. /// Also, this occurs if the pipeline was already stopped. /// </exception> internal bool ShouldProcess( string target, string action) { bool result = true; if (_command != null) { result = _command.ShouldProcess(target, action); } return result; } /// <summary> /// Confirm the operation with the user. /// </summary> /// <param name="verboseDescription"> /// This should contain a textual description of the action to be /// performed. This is what will be displayed to the user for /// ActionPreference.Continue. /// </param> /// <param name="verboseWarning"> /// This should contain a textual query of whether the action /// should be performed, usually in the form of a question. /// This is what will be displayed to the user for /// ActionPreference.Inquire. /// </param> /// <param name="caption"> /// This is the caption of the window which may be displayed /// if the user is prompted whether or not to perform the action. /// It may be displayed by some hosts, but not all. /// </param> /// <remarks>true if-and-only-if the action should be performed</remarks> /// <exception cref="PipelineStoppedException"> /// The ActionPreference.Stop or ActionPreference.Inquire policy /// triggered a terminating error. The pipeline failure will be /// ActionPreferenceStopException. /// Also, this occurs if the pipeline was already stopped. /// </exception> internal bool ShouldProcess( string verboseDescription, string verboseWarning, string caption) { bool result = true; if (_command != null) { result = _command.ShouldProcess( verboseDescription, verboseWarning, caption); } return result; } /// <summary> /// Confirm the operation with the user. /// </summary> /// <param name="verboseDescription"> /// This should contain a textual description of the action to be /// performed. This is what will be displayed to the user for /// ActionPreference.Continue. /// </param> /// <param name="verboseWarning"> /// This should contain a textual query of whether the action /// should be performed, usually in the form of a question. /// This is what will be displayed to the user for /// ActionPreference.Inquire. /// </param> /// <param name="caption"> /// This is the caption of the window which may be displayed /// if the user is prompted whether or not to perform the action. /// It may be displayed by some hosts, but not all. /// </param> /// <param name="shouldProcessReason"> /// Indicates the reason(s) why ShouldProcess returned what it returned. /// Only the reasons enumerated in /// <see cref="System.Management.Automation.ShouldProcessReason"/> /// are returned. /// </param> /// <remarks>true if-and-only-if the action should be performed</remarks> /// <exception cref="PipelineStoppedException"> /// The ActionPreference.Stop or ActionPreference.Inquire policy /// triggered a terminating error. The pipeline failure will be /// ActionPreferenceStopException. /// Also, this occurs if the pipeline was already stopped. /// </exception> internal bool ShouldProcess( string verboseDescription, string verboseWarning, string caption, out ShouldProcessReason shouldProcessReason) { bool result = true; if (_command != null) { result = _command.ShouldProcess( verboseDescription, verboseWarning, caption, out shouldProcessReason); } else { shouldProcessReason = ShouldProcessReason.None; } return result; } /// <summary> /// Ask the user whether to continue/stop or break to a subshell. /// </summary> /// <param name="query"> /// Message to display to the user. This routine will append /// the text "Continue" to ensure that people know what question /// they are answering. /// </param> /// <param name="caption"> /// Dialog caption if the host uses a dialog. /// </param> /// <returns> /// True if the user wants to continue, false if not. /// </returns> internal bool ShouldContinue( string query, string caption) { bool result = true; if (_command != null) { result = _command.ShouldContinue(query, caption); } return result; } /// <summary> /// Ask the user whether to continue/stop or break to a subshell. /// </summary> /// <param name="query"> /// Message to display to the user. This routine will append /// the text "Continue" to ensure that people know what question /// they are answering. /// </param> /// <param name="caption"> /// Dialog caption if the host uses a dialog. /// </param> /// <param name="yesToAll"> /// Indicates whether the user selected YesToAll /// </param> /// <param name="noToAll"> /// Indicates whether the user selected NoToAll /// </param> /// <returns> /// True if the user wants to continue, false if not. /// </returns> internal bool ShouldContinue( string query, string caption, ref bool yesToAll, ref bool noToAll) { bool result = true; if (_command != null) { result = _command.ShouldContinue( query, caption, ref yesToAll, ref noToAll); } else { yesToAll = false; noToAll = false; } return result; } /// <summary> /// Writes the object to the Verbose pipe. /// </summary> /// <param name="text"> /// The string that needs to be written. /// </param> internal void WriteVerbose(string text) => _command?.WriteVerbose(text); /// <summary> /// Writes the object to the Warning pipe. /// </summary> /// <param name="text"> /// The string that needs to be written. /// </param> internal void WriteWarning(string text) => _command?.WriteWarning(text); internal void WriteProgress(ProgressRecord record) => _command?.WriteProgress(record); /// <summary> /// Writes a debug string. /// </summary> /// <param name="text"> /// The String that needs to be written. /// </param> internal void WriteDebug(string text) => _command?.WriteDebug(text); internal void WriteInformation(InformationRecord record) => _command?.WriteInformation(record); internal void WriteInformation(object messageData, string[] tags) => _command?.WriteInformation(messageData, tags); #endregion User feedback mechanisms #endregion Public properties #region Public methods /// <summary> /// Sets the filters that are used within this context. /// </summary> /// <param name="include"> /// The include filters which determines which items are included in /// operations within this context. /// </param> /// <param name="exclude"> /// The exclude filters which determines which items are excluded from /// operations within this context. /// </param> /// <param name="filter"> /// The provider specific filter for the operation. /// </param> internal void SetFilters(Collection<string> include, Collection<string> exclude, string filter) { Include = include; Exclude = exclude; Filter = filter; } /// <summary> /// Gets an array of the objects that have been accumulated /// and the clears the collection. /// </summary> /// <returns> /// An object array of the objects that have been accumulated /// through the WriteObject method. /// </returns> internal Collection<PSObject> GetAccumulatedObjects() { // Get the contents as an array Collection<PSObject> results = _accumulatedObjects; _accumulatedObjects = new Collection<PSObject>(); // Return the array return results; } /// <summary> /// Gets an array of the error objects that have been accumulated /// and the clears the collection. /// </summary> /// <returns> /// An object array of the objects that have been accumulated /// through the WriteError method. /// </returns> internal Collection<ErrorRecord> GetAccumulatedErrorObjects() { // Get the contents as an array Collection<ErrorRecord> results = _accumulatedErrorObjects; _accumulatedErrorObjects = new Collection<ErrorRecord>(); // Return the array return results; } /// <summary> /// If there are any errors accumulated, the first error is thrown. /// </summary> /// <exception cref="ProviderInvocationException"> /// If a CmdletProvider wrote any exceptions to the error pipeline, it is /// wrapped and then thrown. /// </exception> internal void ThrowFirstErrorOrDoNothing() { ThrowFirstErrorOrDoNothing(true); } /// <summary> /// If there are any errors accumulated, the first error is thrown. /// </summary> /// <param name="wrapExceptionInProviderException"> /// If true, the error will be wrapped in a ProviderInvocationException before /// being thrown. If false, the error will be thrown as is. /// </param> /// <exception cref="ProviderInvocationException"> /// If <paramref name="wrapExceptionInProviderException"/> is true, the /// first exception that was written to the error pipeline by a CmdletProvider /// is wrapped and thrown. /// </exception> /// <exception> /// If <paramref name="wrapExceptionInProviderException"/> is false, /// the first exception that was written to the error pipeline by a CmdletProvider /// is thrown. /// </exception> internal void ThrowFirstErrorOrDoNothing(bool wrapExceptionInProviderException) { if (HasErrors()) { Collection<ErrorRecord> errors = GetAccumulatedErrorObjects(); if (errors != null && errors.Count > 0) { // Throw the first exception if (wrapExceptionInProviderException) { ProviderInfo providerInfo = null; if (this.ProviderInstance != null) { providerInfo = this.ProviderInstance.ProviderInfo; } ProviderInvocationException e = new ProviderInvocationException( providerInfo, errors[0]); // Log a provider health event MshLog.LogProviderHealthEvent( this.ExecutionContext, providerInfo != null ? providerInfo.Name : "unknown provider", e, Severity.Warning); throw e; } else { throw errors[0].Exception; } } } } /// <summary> /// Writes all the accumulated errors to the specified context using WriteError. /// </summary> /// <param name="errorContext"> /// The context to write the errors to. /// </param> /// <exception cref="ArgumentNullException"> /// If <paramref name="errorContext"/> is null. /// </exception> internal void WriteErrorsToContext(CmdletProviderContext errorContext) { if (errorContext == null) { throw PSTraceSource.NewArgumentNullException(nameof(errorContext)); } if (HasErrors()) { foreach (ErrorRecord errorRecord in GetAccumulatedErrorObjects()) { errorContext.WriteError(errorRecord); } } } /// <summary> /// Writes an object to the output. /// </summary> /// <param name="obj"> /// The object to be written. /// </param> /// <remarks> /// If streaming is on and the writeObjectHandler was specified then the object /// gets written to the writeObjectHandler. If streaming is on and the writeObjectHandler /// was not specified and the command object was specified, the object gets written to /// the WriteObject method of the command object. /// If streaming is off the object gets written to an accumulator collection. The collection /// of written object can be retrieved using the AccumulatedObjects method. /// </remarks> /// <exception cref="InvalidOperationException"> /// The CmdletProvider could not stream the results because no /// cmdlet was specified to stream the output through. /// </exception> /// <exception cref="PipelineStoppedException"> /// If the pipeline has been signaled for stopping but /// the provider calls this method. /// </exception> internal void WriteObject(object obj) { // Making sure to obey the StopProcessing by // throwing an exception anytime a provider tries // to WriteObject if (Stopping) { PipelineStoppedException stopPipeline = new PipelineStoppedException(); throw stopPipeline; } if (PassThru) { if (_command != null) { s_tracer.WriteLine("Writing to command pipeline"); // Since there was no writeObject handler use // the command WriteObject method. _command.WriteObject(obj); } else { // The flag was set for streaming but we have no where // to stream to. InvalidOperationException e = PSTraceSource.NewInvalidOperationException( SessionStateStrings.OutputStreamingNotEnabled); throw e; } } else { s_tracer.WriteLine("Writing to accumulated objects"); // Convert the object to a PSObject if it's not already // one. PSObject newObj = PSObject.AsPSObject(obj); // Since we are not streaming, just add the object to the accumulatedObjects _accumulatedObjects.Add(newObj); } } /// <summary> /// Writes the error to the pipeline or accumulates the error in an internal /// buffer. /// </summary> /// <param name="errorRecord"> /// The error record to write to the pipeline or the internal buffer. /// </param> /// <exception cref="InvalidOperationException"> /// The CmdletProvider could not stream the error because no /// cmdlet was specified to stream the output through. /// </exception> /// <exception cref="PipelineStoppedException"> /// If the pipeline has been signaled for stopping but /// the provider calls this method. /// </exception> internal void WriteError(ErrorRecord errorRecord) { // Making sure to obey the StopProcessing by // throwing an exception anytime a provider tries // to WriteError if (Stopping) { PipelineStoppedException stopPipeline = new PipelineStoppedException(); throw stopPipeline; } if (_streamErrors) { if (_command != null) { s_tracer.WriteLine("Writing error package to command error pipe"); _command.WriteError(errorRecord); } else { InvalidOperationException e = PSTraceSource.NewInvalidOperationException( SessionStateStrings.ErrorStreamingNotEnabled); throw e; } } else { // Since we are not streaming, just add the object to the accumulatedErrorObjects _accumulatedErrorObjects.Add(errorRecord); if (errorRecord.ErrorDetails != null && errorRecord.ErrorDetails.TextLookupError != null) { Exception textLookupError = errorRecord.ErrorDetails.TextLookupError; errorRecord.ErrorDetails.TextLookupError = null; MshLog.LogProviderHealthEvent( this.ExecutionContext, this.ProviderInstance.ProviderInfo.Name, textLookupError, Severity.Warning); } } } /// <summary> /// If the error pipeline hasn't been supplied a delegate or a command then this method /// will determine if any errors have accumulated. /// </summary> /// <returns> /// True if the errors are being accumulated and some errors have been accumulated. False otherwise. /// </returns> internal bool HasErrors() { return _accumulatedErrorObjects != null && _accumulatedErrorObjects.Count > 0; } /// <summary> /// Call this on a separate thread when a provider is using /// this context to do work. This method will call the StopProcessing /// method of the provider. /// </summary> internal void StopProcessing() { Stopping = true; // We don't need to catch any of the exceptions here because // we are terminating the pipeline and any exception will // be caught by the engine. _providerInstance?.StopProcessing(); // Call the stop referrals if any foreach (CmdletProviderContext referralContext in StopReferrals) { referralContext.StopProcessing(); } } internal bool Stopping { get; private set; } /// <summary> /// The list of contexts to which the StopProcessing calls /// should be referred. /// </summary> internal Collection<CmdletProviderContext> StopReferrals { get; } = new Collection<CmdletProviderContext>(); internal bool HasIncludeOrExclude { get { return ((Include != null && Include.Count > 0) || (Exclude != null && Exclude.Count > 0)); } } #endregion Public methods } }