Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
ExecutionContext.cs1712 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections;5using System.Collections.Generic;6using System.Diagnostics.CodeAnalysis;7using System.Globalization;8using System.IO;9using System.Management.Automation.Host;10using System.Management.Automation.Internal;11using System.Management.Automation.Internal.Host;12using System.Management.Automation.Language;13using System.Management.Automation.Runspaces;14using System.Reflection;15using System.Runtime.CompilerServices;16using System.Security;17 18using Microsoft.PowerShell;19using Microsoft.PowerShell.Commands.Internal.Format;20 21namespace System.Management.Automation22{23    /// <summary>24    /// This class contains the execution context that gets passed25    /// around to commands. This is all of the information that lets you get26    /// at session state and the host interfaces.27    /// </summary>28    internal class ExecutionContext29    {30        #region Properties31 32        /// <summary>33        /// The events received by this runspace.34        /// </summary>35        internal PSLocalEventManager Events { get; private set; }36 37        internal HashSet<string> AutoLoadingModuleInProgress { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);38 39        /// <summary>40        /// The debugger for the interpreter.41        /// </summary>42        internal ScriptDebugger Debugger43        {44            get { return _debugger; }45        }46 47        internal ScriptDebugger _debugger;48 49        internal int _debuggingMode;50 51        /// <summary>52        /// Reset or clear the various context managers so the runspace can be reused without contamination.53        /// </summary>54        internal void ResetManagers()55        {56            _debugger?.ResetDebugger();57 58            Events?.Dispose();59            Events = new PSLocalEventManager(this);60 61            this.transactionManager?.Dispose();62            this.transactionManager = new PSTransactionManager();63        }64        /// <summary>65        /// The tracing mode for the interpreter.66        /// </summary>67        /// <value>True if tracing is turned on, false if it's turned off.</value>68        internal int PSDebugTraceLevel69        {70            get71            {72                // Pretend that tracing is off if ignoreScriptDebug is true73                return IgnoreScriptDebug ? 0 : _debugTraceLevel;74            }75 76            set77            {78                _debugTraceLevel = value;79            }80        }81 82        private int _debugTraceLevel;83 84        /// <summary>85        /// The step mode for the interpreter.86        /// </summary>87        /// <value>True of stepping is turned on, false if it's turned off.</value>88        internal bool PSDebugTraceStep89        {90            get91            {92                // Pretend that tracing is off if ignoreScriptDebug is true93                return !IgnoreScriptDebug && _debugTraceStep;94            }95 96            set97            {98                _debugTraceStep = value;99            }100        }101 102        private bool _debugTraceStep;103 104        // Helper for generated code to handle running w/ no execution context105        internal static bool IsStrictVersion(ExecutionContext context, int majorVersion)106        {107            context ??= LocalPipeline.GetExecutionContextFromTLS();108 109            return (context != null) && context.IsStrictVersion(majorVersion);110        }111        /// <summary>112        /// Check to see a specific version of strict mode is enabled.  The check is always scoped,113        /// even though in version 1 the check was engine wide.114        /// </summary>115        /// <param name="majorVersion">The version for a strict check about to be performed.</param>116        /// <returns></returns>117        internal bool IsStrictVersion(int majorVersion)118        {119            SessionStateScope scope = EngineSessionState.CurrentScope;120            while (scope != null)121            {122                // If StrictModeVersion is null, we haven't seen set-strictmode, so check the parent scope.123                if (scope.StrictModeVersion != null)124                {125                    // If StrictModeVersion is not null, just check the major version.  A version of 0126                    // is the same as off to make this a simple check.127                    return (scope.StrictModeVersion.Major >= majorVersion);128                }129                // We shouldn't check global scope if we were in a module.130                if (scope == EngineSessionState.ModuleScope)131                {132                    break;133                }134 135                scope = scope.Parent;136            }137 138            // set-strictmode hasn't been used.139            return false;140        }141 142        /// <summary>143        /// Is true if the current statement in the interpreter should be traced...144        /// </summary>145        internal bool ShouldTraceStatement146        {147            get148            {149                // Pretend that tracing is off if ignoreScriptDebug is true150                return !IgnoreScriptDebug && (_debugTraceLevel > 0 || _debugTraceStep);151            }152        }153 154        /// <summary>155        /// If true, then a script command processor should rethrow the exit exception instead of156        /// simply capturing it. This is used by the -file option on the console host.157        /// </summary>158        internal bool ScriptCommandProcessorShouldRethrowExit { get; set; } = false;159 160        /// <summary>161        /// If this flag is set to true, script trace output162        /// will not be generated regardless of the state of the163        /// trace flag.164        /// </summary>165        /// <value>The current state of the IgnoreScriptDebug flag.</value>166        internal bool IgnoreScriptDebug { get; set; } = true;167 168        /// <summary>169        /// Gets the automation engine instance.170        /// </summary>171        internal AutomationEngine Engine { get; private set; }172 173        internal InitialSessionState InitialSessionState { get; }174 175        /// <summary>176        /// Added for Win8: 336382177        /// Contains the name of the previous module that was processed. This178        /// allows you to skip this module when doing a lookup.179        /// </summary>180        internal string PreviousModuleProcessed { get; set; }181 182        /// <summary>183        /// Added for 4980967184        /// Contains the name of the latest module that was imported,185        /// Allows "module\function" to call the function from latest imported module instead of randomly choosing the first module in the moduletable.186        /// </summary>187        internal Hashtable previousModuleImported { get; set; } = new Hashtable();188 189        /// <summary>190        /// Contains the name of the module currently being processed. This191        /// allows you to skip this module when doing a lookup.192        /// </summary>193        internal string ModuleBeingProcessed { get; set; }194 195        /// <summary>196        /// Authorization manager for this runspace.197        /// </summary>198        internal AuthorizationManager AuthorizationManager { get; private set; }199 200        /// <summary>201        /// Gets the appropriate provider names for the default202        /// providers based on the type of the shell203        /// (single shell or custom shell).204        /// </summary>205        internal ProviderNames ProviderNames206        {207            get208            {209                _providerNames ??= new SingleShellProviderNames();210 211                return _providerNames;212            }213        }214 215        private ProviderNames _providerNames;216 217        /// <summary>218        /// The module information for this engine...219        /// </summary>220        internal ModuleIntrinsics Modules { get; private set; }221 222        /// <summary>223        /// Get the shellID for this runspace...224        /// </summary>225        internal string ShellID226        {227            get228            {229                if (_shellId == null)230                {231                    // Use the ShellID from PSAuthorizationManager before everything else because that's what's used232                    // to check execution policy...233                    if (AuthorizationManager is PSAuthorizationManager && !string.IsNullOrEmpty(AuthorizationManager.ShellId))234                    {235                        _shellId = AuthorizationManager.ShellId;236                    }237                    else238                    {239                        // Finally fall back to the default shell id...240                        _shellId = Utils.DefaultPowerShellShellID;241                    }242                }243 244                return _shellId;245            }246        }247 248        private string _shellId;249 250        /// <summary>251        /// Session State with which this instance of engine works.252        /// </summary>253        internal SessionStateInternal EngineSessionState { get; set; }254 255        /// <summary>256        /// The default or top-level session state instance for the257        /// engine.258        /// </summary>259        internal SessionStateInternal TopLevelSessionState { get; private set; }260 261        /// <summary>262        /// Get the SessionState facade for the internal session state APIs.263        /// </summary>264        internal SessionState SessionState265        {266            get267            {268                return EngineSessionState.PublicSessionState;269            }270        }271 272        /// <summary>273        /// Get/set constraints for this execution environment.274        /// </summary>275        internal PSLanguageMode LanguageMode276        {277            get278            {279                return _languageMode;280            }281 282            set283            {284                // If we're moving to ConstrainedLanguage, invalidate the binding285                // caches. After that, the binding rules encode the language mode.286                if (value == PSLanguageMode.ConstrainedLanguage)287                {288                    HasRunspaceEverUsedConstrainedLanguageMode = true;289 290                    // If 'ExecutionContext.HasEverUsedConstrainedLanguage' is already set to True, then we have291                    // already invalidated all cached binders, and binders already started to generate code with292                    // consideration of 'LanguageMode'. In such case, we don't need to invalidate cached binders293                    // again.294                    // Note that when executing script blocks marked as 'FullLanguage' in a 'ConstrainedLanguage'295                    // environment, we will set and Restore 'context.LanguageMode' very often. But we should not296                    // invalidate the cached binders every time we restore to 'ConstrainedLanguage'.297                    if (!ExecutionContext.HasEverUsedConstrainedLanguage)298                    {299                        lock (lockObject)300                        {301                            // If another thread has already set 'ExecutionContext.HasEverUsedConstrainedLanguage'302                            // while we are waiting on the lock, then nothing needs to be done.303                            if (!ExecutionContext.HasEverUsedConstrainedLanguage)304                            {305                                PSSetMemberBinder.InvalidateCache();306                                PSInvokeMemberBinder.InvalidateCache();307                                PSConvertBinder.InvalidateCache();308                                PSBinaryOperationBinder.InvalidateCache();309                                PSGetIndexBinder.InvalidateCache();310                                PSSetIndexBinder.InvalidateCache();311                                PSCreateInstanceBinder.InvalidateCache();312 313                                // Set 'HasEverUsedConstrainedLanguage' at the very end to guarantee other threads to wait until314                                // all invalidation operations are done.315                                UntrustedObjects = new ConditionalWeakTable<object, object>();316                                ExecutionContext.HasEverUsedConstrainedLanguage = true;317                            }318                        }319                    }320                }321 322                // Conversion caches don't have version info / binding rules, so must be323                // cleared every time.324                LanguagePrimitives.RebuildConversionCache();325 326                _languageMode = value;327            }328        }329 330        private PSLanguageMode _languageMode = PSLanguageMode.FullLanguage;331 332        /// <summary>333        /// True if this runspace has ever used constrained language mode.334        /// </summary>335        internal bool HasRunspaceEverUsedConstrainedLanguageMode { get; private set; }336 337        /// <summary>338        /// Indicate if a parameter binding is happening that transitions the execution from ConstrainedLanguage339        /// mode to a trusted FullLanguage command.340        /// </summary>341        internal bool LanguageModeTransitionInParameterBinding { get; set; }342 343        /// <summary>344        /// True if we've ever used ConstrainedLanguage. If this is the case, then the binding restrictions345        /// need to also validate against the language mode.346        /// </summary>347        internal static bool HasEverUsedConstrainedLanguage { get; private set; }348 349        #region Variable Tracking350 351        /// <summary>352        /// Initialized when 'ConstrainedLanguage' is applied.353        /// The objects contained in this table are considered to be untrusted.354        /// </summary>355        private static ConditionalWeakTable<object, object> UntrustedObjects { get; set; }356 357        /// <summary>358        /// Helper for checking if the given value is marked as untrusted.359        /// </summary>360        internal static bool IsMarkedAsUntrusted(object value)361        {362            bool result = false;363            var baseValue = PSObject.Base(value);364            if (baseValue != null && baseValue != NullString.Value)365            {366                result = UntrustedObjects.TryGetValue(baseValue, out _);367            }368 369            return result;370        }371 372        /// <summary>373        /// Helper for marking a value as untrusted.374        /// </summary>375        internal static void MarkObjectAsUntrusted(object value)376        {377            // If the value is a PSObject, then we mark its base object untrusted378            var baseValue = PSObject.Base(value);379            if (baseValue != null && baseValue != NullString.Value)380            {381                // It's actually setting a key value pair when the key doesn't exist382                UntrustedObjects.GetValue(baseValue, static key => null);383 384                try385                {386                    // If it's a PSReference object, we need to also mark the value it's holding on.387                    // This could result in a recursion if psRef.Value points to itself directly or indirectly, so we check if psRef.Value is already388                    // marked before making a recursive call. The additional check adds extra overhead for handling PSReference object, but it should389                    // be rare in practice.390                    var psRef = baseValue as PSReference;391                    if (psRef != null && !IsMarkedAsUntrusted(psRef.Value))392                    {393                        MarkObjectAsUntrusted(psRef.Value);394                    }395                }396                catch { /* psRef.Value may call PSVariable.Value under the hood, which may throw arbitrary exception */ }397            }398        }399 400        /// <summary>401        /// Helper for setting the untrusted value of an assignment to either a 'Global:' variable, or a 'Script:' variable in a module scope.402        /// </summary>403        /// <remarks>404        /// This method is for tracking assignment to global variables and module script scope varaibles in ConstrainedLanguage mode. Those variables405        /// can go across boundaries between ConstrainedLanguage and FullLanguage, and make it easy for a trusted script to use data from an untrusted406        /// environment. Therefore, in ConstrainedLanguage mode, we need to mark the value objects assigned to those variables as untrusted.407        /// </remarks>408        internal static void MarkObjectAsUntrustedForVariableAssignment(PSVariable variable, SessionStateScope scope, SessionStateInternal sessionState)409        {410            if (scope.Parent == null ||  // If it's the global scope, OR411                (sessionState.Module != null &&  // it's running in a module AND412                 scope.ScriptScope == scope && scope.Parent.Parent == null)) // it's the module's script scope (scope.Parent is global scope and scope.ScriptScope points to itself)413            {414                // We are setting value for either a 'Global:' variable, or a 'Script:' variable within a module in 'ConstrainedLanguage' mode.415                // Global variable may be referenced within trusted script block (scriptBlock.LanguageMode == 'FullLanguage'), and users could416                // also set a 'Script:' variable in a trusted module scope from 'ConstrainedLanguage' environment via '& $mo { $script:<var> }'.417                // So we need to mark the value as untrusted.418                MarkObjectAsUntrusted(variable.Value);419            }420        }421 422        /// <summary>423        /// The result object is assumed generated by operating on the original object.424        /// So if the original object is from an untrusted input source, we mark the result object as untrusted.425        /// </summary>426        internal static void PropagateInputSource(object originalObject, object resultObject, PSLanguageMode currentLanguageMode)427        {428            // The untrusted flag is populated only in FullLanguage mode and ConstrainedLanguage has been used in the process before.429            if (ExecutionContext.HasEverUsedConstrainedLanguage && currentLanguageMode == PSLanguageMode.FullLanguage && IsMarkedAsUntrusted(originalObject))430            {431                MarkObjectAsUntrusted(resultObject);432            }433        }434 435        #endregion436 437        /// <summary>438        /// If true the PowerShell debugger will use FullLanguage mode, otherwise it will use the current language mode.439        /// </summary>440        internal bool UseFullLanguageModeInDebugger441        {442            get443            {444                return InitialSessionState != null && InitialSessionState.UseFullLanguageModeInDebugger;445            }446        }447 448        internal static readonly List<string> ModulesWithJobSourceAdapters = new List<string>449            {450                Utils.ScheduledJobModuleName,451            };452 453        /// <summary>454        /// Is true if the PSScheduledJob module is loaded for this runspace.455        /// </summary>456        internal bool IsModuleWithJobSourceAdapterLoaded457        {458            get; set;459        }460 461        /// <summary>462        /// Gets the location globber for the session state for463        /// this instance of the runspace.464        /// </summary>465        internal LocationGlobber LocationGlobber466        {467            get468            {469                _locationGlobber = new LocationGlobber(this.SessionState);470                return _locationGlobber;471            }472        }473 474        private LocationGlobber _locationGlobber;475 476        /// <summary>477        /// The assemblies that have been loaded for this runspace.478        /// </summary>479        internal Dictionary<string, Assembly> AssemblyCache { get; private set; }480        #endregion Properties481 482        #region Engine State483 484        /// <summary>485        /// The state for current engine that is running.486        /// </summary>487        /// <value></value>488        internal EngineState EngineState { get; set; } = EngineState.None;489 490        #endregion491 492        #region GetSetVariable methods493 494        /// <summary>495        /// Get a variable out of session state.496        /// </summary>497        internal object GetVariableValue(VariablePath path)498        {499            CmdletProviderContext context;500            SessionStateScope scope;501            return EngineSessionState.GetVariableValue(path, out context, out scope);502        }503 504        /// <summary>505        /// Get a variable out of session state. This calls GetVariable(name) and returns the506        /// value unless it is null in which case it returns the defaultValue provided by the caller.507        /// </summary>508        internal object GetVariableValue(VariablePath path, object defaultValue)509        {510            return EngineSessionState.GetVariableValue(path, out _, out _) ?? defaultValue;511        }512 513        /// <summary>514        /// Set a variable in session state.515        /// </summary>516        internal void SetVariable(VariablePath path, object newValue)517        {518            EngineSessionState.SetVariable(path, newValue, true, CommandOrigin.Internal);519        }520 521        internal T GetEnumPreference<T>(VariablePath preferenceVariablePath, T defaultPref, out bool defaultUsed)522        {523            object val = EngineSessionState.GetVariableValue(preferenceVariablePath, out _, out _);524            if (val is T)525            {526                if (val is ActionPreference actionPreferenceValue)527                {528                    CheckActionPreference(preferenceVariablePath, actionPreferenceValue, defaultPref);529                }530 531                T convertedResult = (T)val;532 533                defaultUsed = false;534                return convertedResult;535            }536 537            defaultUsed = true;538            T result = defaultPref;539 540            if (val != null)541            {542                try543                {544                    string valString = val as string;545                    if (valString != null)546                    {547                        result = (T)Enum.Parse(typeof(T), valString, true);548                        defaultUsed = false;549                    }550                    else551                    {552                        result = (T)PSObject.Base(val);553                        defaultUsed = false;554                    }555 556                    if (result is ActionPreference actionPreferenceValue)557                    {558                        CheckActionPreference(preferenceVariablePath, actionPreferenceValue, defaultPref);559                    }560                }561                catch (InvalidCastException)562                {563                    // default value is used564                }565                catch (ArgumentException)566                {567                    // default value is used568                }569            }570 571            return result;572        }573 574        private void CheckActionPreference(VariablePath preferenceVariablePath, ActionPreference preference, object defaultValue)575        {576            if (preference == ActionPreference.Suspend)577            {578                // ActionPreference.Suspend is reserved for future use. When it is used, reset579                // the variable to its default.580                string message = StringUtil.Format(ErrorPackage.ReservedActionPreferenceReplacedError, preference, preferenceVariablePath.UserPath, defaultValue);581                EngineSessionState.SetVariable(preferenceVariablePath, defaultValue, true, CommandOrigin.Internal);582                throw new NotSupportedException(message);583            }584        }585 586        /// <summary>587        /// Same as GetEnumPreference, but for boolean values.588        /// </summary>589        /// <param name="preferenceVariablePath"></param>590        /// <param name="defaultPref"></param>591        /// <param name="defaultUsed"></param>592        /// <returns></returns>593        internal bool GetBooleanPreference(VariablePath preferenceVariablePath, bool defaultPref, out bool defaultUsed)594        {595            object val = EngineSessionState.GetVariableValue(preferenceVariablePath, out _, out _);596            if (val is null)597            {598                defaultUsed = true;599                return defaultPref;600            }601 602            defaultUsed = !LanguagePrimitives.TryConvertTo(val, out bool converted);603            return defaultUsed ? defaultPref : converted;604        }605        #endregion GetSetVariable methods606 607        #region HelpSystem608 609        /// <summary>610        /// Help system for this engine context.611        /// </summary>612        /// <value></value>613        internal HelpSystem HelpSystem614        {615            get { return _helpSystem ??= new HelpSystem(this); }616        }617 618        private HelpSystem _helpSystem;619 620        #endregion621 622        #region FormatAndOutput623        internal object FormatInfo { get; set; }624 625        #endregion626 627        internal Dictionary<string, ScriptBlock> CustomArgumentCompleters { get; set; }628 629        internal Dictionary<string, ScriptBlock> NativeArgumentCompleters { get; set; }630 631        /// <summary>632        /// Routine to create a command(processor) instance using the factory.633        /// </summary>634        /// <param name="command">The name of the command to lookup.</param>635        /// <param name="dotSource"></param>636        /// <param name="forCompletion"></param>637        /// <returns>The command processor object.</returns>638        internal CommandProcessorBase CreateCommand(string command, bool dotSource, bool forCompletion = false)639        {640            CommandOrigin commandOrigin = this.EngineSessionState.CurrentScope.ScopeOrigin;641            CommandProcessorBase commandProcessor =642                CommandDiscovery.LookupCommandProcessor(command, commandOrigin, !dotSource, forCompletion);643            // Reset the command origin for script commands... // BUGBUG - dotting can get around command origin checks???644            if (commandProcessor != null && commandProcessor is ScriptCommandProcessorBase)645            {646                commandProcessor.Command.CommandOriginInternal = CommandOrigin.Internal;647            }648 649            return commandProcessor;650        }651 652        /// <summary>653        /// Hold the current command.654        /// </summary>655        /// <value>Reference to command discovery</value>656        internal CommandProcessorBase CurrentCommandProcessor { get; set; }657 658        /// <summary>659        /// Redirect to the CommandDiscovery in the engine.660        /// </summary>661        /// <value>Reference to command discovery</value>662        internal CommandDiscovery CommandDiscovery663        {664            get665            {666                return Engine.CommandDiscovery;667            }668        }669 670        /// <summary>671        /// Interface that should be used for interaction with host.672        /// </summary>673        internal InternalHost EngineHostInterface674        {675            // set not provided: it's not meaningful to change the host post-construction.676            get; private set;677        }678 679        /// <summary>680        /// Interface to be used for interaction with internal681        /// host. InternalHost wraps the host supplied682        /// during construction. Use this wrapper to access683        /// functionality specific to InternalHost.684        /// </summary>685        internal InternalHost InternalHost686        {687            get { return EngineHostInterface; }688        }689 690        /// <summary>691        /// Interface to the public API for the engine.692        /// </summary>693        internal EngineIntrinsics EngineIntrinsics694        {695            get { return _engineIntrinsics ??= new EngineIntrinsics(this); }696        }697 698        private EngineIntrinsics _engineIntrinsics;699 700        /// <summary>701        /// Log context cache.702        /// </summary>703        internal LogContextCache LogContextCache { get; } = new LogContextCache();704 705        #region Output pipes706        /// <summary>707        /// The PipelineWriter provided by the connection object for success output.708        /// </summary>709        internal PipelineWriter ExternalSuccessOutput { get; set; }710 711        /// <summary>712        /// The PipelineWriter provided by the connection object for error output.713        /// </summary>714        internal PipelineWriter ExternalErrorOutput { get; set; }715 716        /// <summary>717        /// The PipelineWriter provided by the connection object for progress output.718        /// </summary>719        internal PipelineWriter ExternalProgressOutput { get; set; }720 721        internal class SavedContextData722        {723            private readonly bool _stepScript;724            private readonly bool _ignoreScriptDebug;725            private readonly int _PSDebug;726 727            private readonly Pipe _shellFunctionErrorOutputPipe;728 729            public SavedContextData(ExecutionContext context)730            {731                _stepScript = context.PSDebugTraceStep;732                _ignoreScriptDebug = context.IgnoreScriptDebug;733                _PSDebug = context.PSDebugTraceLevel;734 735                _shellFunctionErrorOutputPipe = context.ShellFunctionErrorOutputPipe;736            }737 738            public void RestoreContextData(ExecutionContext context)739            {740                context.PSDebugTraceStep = _stepScript;741                context.IgnoreScriptDebug = _ignoreScriptDebug;742                context.PSDebugTraceLevel = _PSDebug;743 744                context.ShellFunctionErrorOutputPipe = _shellFunctionErrorOutputPipe;745            }746        }747 748        /// <summary>749        /// Host uses this to saves context data when entering a nested prompt.750        /// </summary>751        /// <returns></returns>752        internal SavedContextData SaveContextData()753        {754            return new SavedContextData(this);755        }756 757        internal void ResetShellFunctionErrorOutputPipe()758        {759            ShellFunctionErrorOutputPipe = null;760        }761 762        internal Pipe RedirectErrorPipe(Pipe newPipe)763        {764            Pipe oldPipe = ShellFunctionErrorOutputPipe;765            ShellFunctionErrorOutputPipe = newPipe;766            return oldPipe;767        }768 769        /// <summary>770        /// Reset all of the redirection book keeping variables. This routine should be called when starting to771        /// execute a script.772        /// </summary>773        internal void ResetRedirection()774        {775            ShellFunctionErrorOutputPipe = null;776        }777 778        /// <summary>779        /// Function and Script command processors will route their error output to780        /// this pipe if set, unless explicitly routed elsewhere. We also keep track781        /// of the first time this value is set so we can know if it's the default782        /// error output or not.783        /// </summary>784        internal Pipe ShellFunctionErrorOutputPipe { get; set; }785 786        /// <summary>787        /// Supports expression Warning output redirection.788        /// </summary>789        internal Pipe ExpressionWarningOutputPipe { get; set; }790 791        /// <summary>792        /// Supports expression Verbose output redirection.793        /// </summary>794        internal Pipe ExpressionVerboseOutputPipe { get; set; }795 796        /// <summary>797        /// Supports expression Verbose output redirection.798        /// </summary>799        internal Pipe ExpressionDebugOutputPipe { get; set; }800 801        /// <summary>802        /// Supports expression Information output redirection.803        /// </summary>804        internal Pipe ExpressionInformationOutputPipe { get; set; }805 806        #endregion Output pipes807 808        #region Append to $error809        /// <summary>810        /// Appends the object to $global:error if it's an error record or exception.811        /// </summary>812        /// <param name="obj">813        /// ErrorRecord or Exception to be written to $global:error814        /// </param>815        /// <exception cref="ExtendedTypeSystemException">816        /// (get-only) An error occurred accessing $ERROR.817        /// </exception>818        internal void AppendDollarError(object obj)819        {820            ErrorRecord objAsErrorRecord = obj as ErrorRecord;821            if (objAsErrorRecord is null && obj is not Exception)822            {823                Diagnostics.Assert(false, "Object to append was neither an ErrorRecord nor an Exception in ExecutionContext.AppendDollarError");824                return;825            }826 827            if (DollarErrorVariable is not ArrayList arraylist)828            {829                Diagnostics.Assert(false, "$error should be a global constant ArrayList");830                return;831            }832 833            // Don't add the same exception twice...834            if (arraylist.Count > 0)835            {836                // There may be exceptions stored directly in which case837                // the direct comparison will catch them...838                if (arraylist[0] == obj)839                    return;840                // otherwise check the exception members of the error records...841                ErrorRecord er1 = arraylist[0] as ErrorRecord;842 843                if (er1 != null && objAsErrorRecord != null && er1.Exception == objAsErrorRecord.Exception)844                    return;845            }846 847            const int maxErrorCount = 256;848 849            int numToErase = arraylist.Count - (maxErrorCount - 1);850            if (numToErase > 0)851            {852                arraylist.RemoveRange(853                    maxErrorCount - 1,854                    numToErase);855            }856 857            arraylist.Insert(0, obj);858        }859        #endregion860 861        #region Scope or Commands (in pipeline) Depth Count862 863        /// <summary>864        /// Check if the stack would overflow soon, if so, throw ScriptCallDepthException.865        /// </summary>866        /// <exception cref="ScriptCallDepthException">867        /// If the stack would overflow soon.868        /// </exception>869        internal static void CheckStackDepth()870        {871            try872            {873                RuntimeHelpers.EnsureSufficientExecutionStack();874            }875            catch (InsufficientExecutionStackException)876            {877                throw new ScriptCallDepthException();878            }879        }880 881        #endregion882 883        /// <summary>884        /// The current connection object.885        /// </summary>886        private Runspace _currentRunspace;887        // This should be internal, but it need to be friend of remoting dll.888        /// <summary>889        /// The current connection object.890        /// </summary>891        internal Runspace CurrentRunspace892        {893            get { return _currentRunspace; }894 895            set { _currentRunspace = value; }896        }897 898        /// <summary>899        /// Each pipeline has a stack of pipeline processor. This method900        /// pushes pp in to stack for currently executing pipeline.901        /// </summary>902        /// <param name="pp"></param>903        internal void PushPipelineProcessor(PipelineProcessor pp)904        {905            if (_currentRunspace == null)906                return;907            LocalPipeline lpl = (LocalPipeline)((RunspaceBase)_currentRunspace).GetCurrentlyRunningPipeline();908            if (lpl == null)909                return;910            lpl.Stopper.Push(pp);911        }912 913        /// <summary>914        /// Each pipeline has a stack of pipeline processor. This method pops the915        /// top item from the stack.916        /// </summary>917        internal void PopPipelineProcessor(bool fromSteppablePipeline)918        {919            if (_currentRunspace == null)920                return;921            LocalPipeline lpl = (LocalPipeline)((RunspaceBase)_currentRunspace).GetCurrentlyRunningPipeline();922            if (lpl == null)923                return;924            lpl.Stopper.Pop(fromSteppablePipeline);925        }926 927        /// <summary>928        /// This flag is checked by parser to stop loops etc.929        /// </summary>930        /// <returns></returns>931        internal bool CurrentPipelineStopping932        {933            get934            {935                if (_currentRunspace == null)936                    return false;937                LocalPipeline lpl = (LocalPipeline)((RunspaceBase)_currentRunspace).GetCurrentlyRunningPipeline();938                if (lpl == null)939                    return false;940                return lpl.IsStopping;941            }942        }943 944        /// <summary>945        /// True means one of these:946        /// 1) there is a trap statement in a dynamically enclosing statement block that might catch an exception.947        /// 2) execution happens inside a PS class and exceptions should be propagated all the way up, even if there is no enclosing try-catch-finally.948        /// </summary>949        /// <value></value>950        internal bool PropagateExceptionsToEnclosingStatementBlock { get; set; }951 952        internal RuntimeException CurrentExceptionBeingHandled { get; set; }953 954        /// <summary>955        /// Shortcut to get at $?956        /// </summary>957        /// <value>The current value of $? </value>958        internal bool QuestionMarkVariableValue { get; set; } = true;959 960        /// <summary>961        /// Shortcut to get at $error.962        /// </summary>963        /// <value>The current value of $global:error </value>964        internal object DollarErrorVariable965        {966            get967            {968                CmdletProviderContext context = null;969                SessionStateScope scope = null;970                object resultItem = null;971 972                if (!Events.IsExecutingEventAction)973                {974                    resultItem = EngineSessionState.GetVariableValue(975                        SpecialVariables.ErrorVarPath, out context, out scope);976                }977                else978                {979                    resultItem = EngineSessionState.GetVariableValue(980                        SpecialVariables.EventErrorVarPath, out context, out scope);981                }982 983                return resultItem;984            }985 986            set987            {988                EngineSessionState.SetVariable(989                    SpecialVariables.ErrorVarPath, value, true, CommandOrigin.Internal);990            }991        }992 993        internal ActionPreference DebugPreferenceVariable994        {995            get996            {997                bool defaultUsed = false;998                return this.GetEnumPreference(999                    SpecialVariables.DebugPreferenceVarPath,1000                    InitialSessionState.DefaultDebugPreference,1001                    out defaultUsed);1002            }1003 1004            set1005            {1006                this.EngineSessionState.SetVariable(1007                    SpecialVariables.DebugPreferenceVarPath,1008                    LanguagePrimitives.ConvertTo(value, typeof(ActionPreference), CultureInfo.InvariantCulture),1009                    true,1010                    CommandOrigin.Internal);1011            }1012        }1013 1014        internal ActionPreference VerbosePreferenceVariable1015        {1016            get1017            {1018                bool defaultUsed = false;1019                return this.GetEnumPreference(1020                    SpecialVariables.VerbosePreferenceVarPath,1021                    InitialSessionState.DefaultVerbosePreference,1022                    out defaultUsed);1023            }1024 1025            set1026            {1027                this.EngineSessionState.SetVariable(1028                    SpecialVariables.VerbosePreferenceVarPath,1029                    LanguagePrimitives.ConvertTo(value, typeof(ActionPreference), CultureInfo.InvariantCulture),1030                    true,1031                    CommandOrigin.Internal);1032            }1033        }1034 1035        internal ActionPreference ErrorActionPreferenceVariable1036        {1037            get1038            {1039                bool defaultUsed = false;1040                return this.GetEnumPreference(1041                    SpecialVariables.ErrorActionPreferenceVarPath,1042                    InitialSessionState.DefaultErrorActionPreference,1043                    out defaultUsed);1044            }1045 1046            set1047            {1048                this.EngineSessionState.SetVariable(1049                    SpecialVariables.ErrorActionPreferenceVarPath,1050                    LanguagePrimitives.ConvertTo(value, typeof(ActionPreference), CultureInfo.InvariantCulture),1051                    true,1052                    CommandOrigin.Internal);1053            }1054        }1055 1056        internal ActionPreference WarningActionPreferenceVariable1057        {1058            get1059            {1060                bool defaultUsed = false;1061                return this.GetEnumPreference(1062                    SpecialVariables.WarningPreferenceVarPath,1063                    InitialSessionState.DefaultWarningPreference,1064                    out defaultUsed);1065            }1066 1067            set1068            {1069                this.EngineSessionState.SetVariable(1070                    SpecialVariables.WarningPreferenceVarPath,1071                    LanguagePrimitives.ConvertTo(value, typeof(ActionPreference), CultureInfo.InvariantCulture),1072                    true,1073                    CommandOrigin.Internal);1074            }1075        }1076 1077        internal ActionPreference InformationActionPreferenceVariable1078        {1079            get1080            {1081                bool defaultUsed = false;1082                return this.GetEnumPreference(1083                    SpecialVariables.InformationPreferenceVarPath,1084                    InitialSessionState.DefaultInformationPreference,1085                    out defaultUsed);1086            }1087 1088            set1089            {1090                this.EngineSessionState.SetVariable(1091                    SpecialVariables.InformationPreferenceVarPath,1092                    LanguagePrimitives.ConvertTo(value, typeof(ActionPreference), CultureInfo.InvariantCulture),1093                    true,1094                    CommandOrigin.Internal);1095            }1096        }1097 1098        internal object WhatIfPreferenceVariable1099        {1100            get1101            {1102                CmdletProviderContext context = null;1103                SessionStateScope scope = null;1104 1105                object resultItem = this.EngineSessionState.GetVariableValue(1106                    SpecialVariables.WhatIfPreferenceVarPath,1107                    out context,1108                    out scope);1109 1110                return resultItem;1111            }1112 1113            set1114            {1115                this.EngineSessionState.SetVariable(1116                    SpecialVariables.WhatIfPreferenceVarPath,1117                    value,1118                    true,1119                    CommandOrigin.Internal);1120            }1121        }1122 1123        internal ConfirmImpact ConfirmPreferenceVariable1124        {1125            get1126            {1127                bool defaultUsed = false;1128                return this.GetEnumPreference(1129                    SpecialVariables.ConfirmPreferenceVarPath,1130                    InitialSessionState.DefaultConfirmPreference,1131                    out defaultUsed);1132            }1133 1134            set1135            {1136                this.EngineSessionState.SetVariable(1137                    SpecialVariables.ConfirmPreferenceVarPath,1138                    LanguagePrimitives.ConvertTo(value, typeof(ConfirmImpact), CultureInfo.InvariantCulture),1139                    true,1140                    CommandOrigin.Internal);1141            }1142        }1143 1144        internal void RunspaceClosingNotification()1145        {1146            EngineSessionState.RunspaceClosingNotification();1147 1148            _debugger?.Dispose();1149 1150            Events?.Dispose();1151            Events = null;1152 1153            this.transactionManager?.Dispose();1154            this.transactionManager = null;1155        }1156 1157        /// <summary>1158        /// Gets the type table instance for this engine.1159        /// </summary>1160        internal TypeTable TypeTable1161        {1162            get1163            {1164                if (_typeTable == null)1165                {1166                    _typeTable = new TypeTable();1167                    _typeTableWeakReference = new WeakReference<TypeTable>(_typeTable);1168                }1169 1170                return _typeTable;1171            }1172 1173            set1174            {1175                _typeTable = value;1176                _typeTableWeakReference = (value != null) ? new WeakReference<TypeTable>(value) : null;1177            }1178        }1179 1180        /// <summary>1181        /// Here for PSObject, should probably not be used elsewhere, maybe not even in PSObject.1182        /// </summary>1183        internal WeakReference<TypeTable> TypeTableWeakReference1184        {1185            get1186            {1187                if (_typeTable == null)1188                {1189                    var unused = TypeTable;1190                }1191 1192                return _typeTableWeakReference;1193            }1194        }1195 1196        private TypeTable _typeTable;1197        private WeakReference<TypeTable> _typeTableWeakReference;1198 1199        /// <summary>1200        /// Gets the format info database for this engine.

Showing the first 1,200 of 1712 lines. Download the file for the rest.