Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
LocalConnection.cs1570 linesDownload Raw Back to hostifaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections;5using System.Collections.Generic;6using System.Collections.ObjectModel;7using System.Diagnostics;8using System.Diagnostics.CodeAnalysis; // for fxcop9using System.IO;10using System.Linq;11using System.Management.Automation.Host;12using System.Management.Automation.Internal;13using System.Management.Automation.Remoting;14using System.Runtime.Serialization;15using System.Threading;16 17using Microsoft.PowerShell.Commands;18 19using Dbg = System.Management.Automation.Diagnostics;20#if LEGACYTELEMETRY21using Microsoft.PowerShell.Telemetry.Internal;22#endif23 24#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings25 26namespace System.Management.Automation.Runspaces27{28    /// <summary>29    /// Runspace class for local runspace.30    /// </summary>31    internal sealed partial class LocalRunspace : RunspaceBase32    {33        #region constructors34 35        /// <summary>36        /// Construct an instance of an Runspace using a custom implementation37        /// of PSHost.38        /// </summary>39        /// <param name="host">40        /// The explicit PSHost implementation41        /// </param>42        /// <param name="initialSessionState">43        /// configuration information for this minshell.44        /// </param>45        /// <param name="suppressClone">46        /// If true, don't make a copy of the initial session state object47        /// </param>48        [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]49        internal LocalRunspace(PSHost host, InitialSessionState initialSessionState, bool suppressClone)50            : base(host, initialSessionState, suppressClone)51        {52        }53 54        /// <summary>55        /// Construct an instance of an Runspace using a custom implementation56        /// of PSHost.57        /// </summary>58        /// <param name="host">59        /// The explicit PSHost implementation60        /// </param>61        /// <param name="initialSessionState">62        /// configuration information for this minshell.63        /// </param>64        [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]65        internal LocalRunspace(PSHost host, InitialSessionState initialSessionState)66            : base(host, initialSessionState)67        {68        }69        #endregion constructors70 71        /// <summary>72        /// Private data to be used by applications built on top of PowerShell.73        ///74        /// Local runspace pool is created with application private data set to an empty <see cref="PSPrimitiveDictionary"/>.75        ///76        /// Runspaces that are part of a <see cref="RunspacePool"/> inherit application private data from the pool.77        /// </summary>78        public override PSPrimitiveDictionary GetApplicationPrivateData()79        {80            // if we didn't get applicationPrivateData from a runspace pool,81            // then we create a new one82 83            if (_applicationPrivateData == null)84            {85                lock (this.SyncRoot)86                {87                    _applicationPrivateData ??= new PSPrimitiveDictionary();88                }89            }90 91            return _applicationPrivateData;92        }93 94        /// <summary>95        /// A method that runspace pools can use to propagate application private data into runspaces.96        /// </summary>97        /// <param name="applicationPrivateData"></param>98        internal override void SetApplicationPrivateData(PSPrimitiveDictionary applicationPrivateData)99        {100            _applicationPrivateData = applicationPrivateData;101        }102 103        private PSPrimitiveDictionary _applicationPrivateData;104 105        /// <summary>106        /// Gets the event manager.107        /// </summary>108        public override PSEventManager Events109        {110            get111            {112                System.Management.Automation.ExecutionContext context = this.GetExecutionContext;113 114                if (context == null)115                {116                    return null;117                }118 119                return context.Events;120            }121        }122 123        /// <summary>124        /// This property determines whether a new thread is create for each invocation.125        /// </summary>126        /// <remarks>127        /// Any updates to the value of this property must be done before the Runspace is opened128        /// </remarks>129        /// <exception cref="InvalidRunspaceStateException">130        /// An attempt to change this property was made after opening the Runspace131        /// </exception>132        /// <exception cref="InvalidOperationException">133        /// The thread options cannot be changed to the requested value134        /// </exception>135        public override PSThreadOptions ThreadOptions136        {137            get138            {139                return _createThreadOptions;140            }141 142            set143            {144                lock (this.SyncRoot)145                {146                    if (value == _createThreadOptions)147                    {148                        return;149                    }150 151                    if (this.RunspaceStateInfo.State != RunspaceState.BeforeOpen)152                    {153                        if (!IsValidThreadOptionsConfiguration(value))154                        {155                            throw new InvalidOperationException(StringUtil.Format(RunspaceStrings.InvalidThreadOptionsChange));156                        }157                    }158 159                    _createThreadOptions = value;160                }161            }162        }163 164        private bool IsValidThreadOptionsConfiguration(PSThreadOptions options)165        {166            // If the runspace is already opened, we only allow changing options when:167            //  - The new value is ReuseThread, and168            //  - The apartment state is not STA169            return options == PSThreadOptions.ReuseThread && this.ApartmentState != ApartmentState.STA;170        }171 172        private PSThreadOptions _createThreadOptions = PSThreadOptions.Default;173 174        /// <summary>175        /// Resets the runspace state to allow for fast reuse. Not all of the runspace176        /// elements are reset. The goal is to minimize the chance of the user taking177        /// accidental dependencies on prior runspace state.178        /// </summary>179        public override void ResetRunspaceState()180        {181            PSInvalidOperationException invalidOperation = null;182 183            if (this.InitialSessionState == null)184            {185                invalidOperation = PSTraceSource.NewInvalidOperationException();186            }187            else if (this.RunspaceState != Runspaces.RunspaceState.Opened)188            {189                invalidOperation = PSTraceSource.NewInvalidOperationException(190                        RunspaceStrings.RunspaceNotInOpenedState, this.RunspaceState);191            }192            else if (this.RunspaceAvailability != Runspaces.RunspaceAvailability.Available)193            {194                invalidOperation = PSTraceSource.NewInvalidOperationException(195                        RunspaceStrings.ConcurrentInvokeNotAllowed);196            }197 198            if (invalidOperation != null)199            {200                invalidOperation.Source = "ResetRunspaceState";201                throw invalidOperation;202            }203 204            this.InitialSessionState.ResetRunspaceState(this.ExecutionContext);205 206            // Finally, reset history for this runspace. This needs to be done207            // last to so that changes to the default MaximumHistorySize will be picked up.208            _history = new History(this.ExecutionContext);209        }210 211        #region protected_methods212 213        /// <summary>214        /// Create a pipeline from a command string.215        /// </summary>216        /// <param name="command">A valid command string. Can be null.</param>217        /// <param name="addToHistory">If true command is added to history.</param>218        /// <param name="isNested">True for nested pipeline.</param>219        /// <returns>220        /// A pipeline pre-filled with Commands specified in commandString.221        /// </returns>222        protected override Pipeline CoreCreatePipeline(string command, bool addToHistory, bool isNested)223        {224            // NTRAID#Windows Out Of Band Releases-915851-2005/09/13225            if (_disposed)226            {227                throw PSTraceSource.NewObjectDisposedException("runspace");228            }229 230            return (Pipeline)new LocalPipeline(this, command, addToHistory, isNested);231        }232 233        #endregion protected_methods234 235        #region protected_properties236 237        /// <summary>238        /// Gets the execution context.239        /// </summary>240        internal override ExecutionContext GetExecutionContext241        {242            get243            {244                if (_engine == null)245                    return null;246                else247                    return _engine.Context;248            }249        }250 251        /// <summary>252        /// Returns true if the internal host is in a nested prompt.253        /// </summary>254        internal override bool InNestedPrompt255        {256            get257            {258                System.Management.Automation.ExecutionContext context = this.GetExecutionContext;259 260                if (context == null)261                {262                    return false;263                }264 265                return context.InternalHost.HostInNestedPrompt() || InInternalNestedPrompt;266            }267        }268 269        /// <summary>270        /// Allows internal nested commands to be run as "HostInNestedPrompt" so that CreatePipelineProcessor() does271        /// not set CommandOrigin to Internal as it normally does by default.  This then allows cmdlets like Invoke-History272        /// to replay history command lines in the current runspace with the same language mode context as the host.273        /// </summary>274        internal bool InInternalNestedPrompt275        {276            get;277            set;278        }279 280        #endregion protected_properties281 282        #region internal_properties283 284        /// <summary>285        /// Gets history manager for this runspace.286        /// </summary>287        /// <value></value>288        internal History History289        {290            get291            {292                return _history;293            }294        }295 296        /// <summary>297        /// Gets transcription data for this runspace.298        /// </summary>299        /// <value></value>300        internal TranscriptionData TranscriptionData301        {302            get303            {304                return _transcriptionData;305            }306        }307 308        private TranscriptionData _transcriptionData = null;309 310        private JobRepository _jobRepository;311        /// <summary>312        /// List of jobs in this runspace.313        /// </summary>314        internal JobRepository JobRepository315        {316            get317            {318                return _jobRepository;319            }320        }321 322        private JobManager _jobManager;323 324        /// <summary>325        /// Manager for JobSourceAdapters registered in this runspace.326        /// </summary>327        public override JobManager JobManager328        {329            get330            {331                return _jobManager;332            }333        }334 335        private RunspaceRepository _runspaceRepository;336 337        /// <summary>338        /// List of remote runspaces in this runspace.339        /// </summary>340        internal RunspaceRepository RunspaceRepository341        {342            get343            {344                return _runspaceRepository;345            }346        }347 348        #endregion internal_properties349 350        #region Debugger351 352        /// <summary>353        /// Debugger.354        /// </summary>355        public override Debugger Debugger356        {357            get358            {359                return InternalDebugger ?? base.Debugger;360            }361        }362 363        private static readonly string s_debugPreferenceCachePath = Path.Combine(Platform.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "WindowsPowerShell", "DebugPreference.clixml");364        private static readonly object s_debugPreferenceLockObject = new object();365 366        /// <summary>367        /// DebugPreference serves as a property bag to keep368        /// track of all process specific debug preferences.369        /// </summary>370        public class DebugPreference371        {372            public string[] AppDomainNames;373        }374 375        /// <summary>376        /// CreateDebugPerfStruct is a helper method to populate DebugPreference.377        /// </summary>378        /// <param name="AppDomainNames">App Domain Names.</param>379        /// <returns>DebugPreference.</returns>380        private static DebugPreference CreateDebugPreference(string[] AppDomainNames)381        {382            DebugPreference DebugPreference = new DebugPreference();383            DebugPreference.AppDomainNames = AppDomainNames;384            return DebugPreference;385        }386 387        /// <summary>388        /// SetDebugPreference is a helper method used to enable and disable debug preference.389        /// </summary>390        /// <param name="processName">Process Name.</param>391        /// <param name="appDomainName">App Domain Name.</param>392        /// <param name="enable">Indicates if the debug preference has to be enabled or disabled.</param>393        internal static void SetDebugPreference(string processName, List<string> appDomainName, bool enable)394        {395            lock (s_debugPreferenceLockObject)396            {397                bool iscacheUpdated = false;398                Hashtable debugPreferenceCache = null;399 400                string[] appDomainNames = null;401                if (appDomainName != null)402                {403                    appDomainNames = appDomainName.ToArray();404                }405 406                if (!File.Exists(LocalRunspace.s_debugPreferenceCachePath))407                {408                    if (enable)409                    {410                        DebugPreference DebugPreference = CreateDebugPreference(appDomainNames);411                        debugPreferenceCache = new Hashtable();412                        debugPreferenceCache.Add(processName, DebugPreference);413                        iscacheUpdated = true;414                    }415                }416                else417                {418                    debugPreferenceCache = GetDebugPreferenceCache(null);419                    if (debugPreferenceCache != null)420                    {421                        if (enable)422                        {423                            // Debug preference is set to enable.424                            // If the cache does not contain the process name, then we just update the cache.425                            if (!debugPreferenceCache.ContainsKey(processName))426                            {427                                DebugPreference DebugPreference = CreateDebugPreference(appDomainNames);428                                debugPreferenceCache.Add(processName, DebugPreference);429                                iscacheUpdated = true;430                            }431                            else432                            {433                                // In this case, the cache contains the process name, hence we check the list of434                                // app domains for which the debug preference is set to enable.435                                DebugPreference processDebugPreference = GetProcessSpecificDebugPreference(debugPreferenceCache[processName]);436 437                                // processDebugPreference would point to null if debug preference is enabled for all app domains.438                                // If processDebugPreference is not null then it means that user has selected specific439                                // appdomins for which the debug preference has to be enabled.440                                if (processDebugPreference != null)441                                {442                                    List<string> cachedAppDomainNames = null;443                                    if (processDebugPreference.AppDomainNames != null && processDebugPreference.AppDomainNames.Length > 0)444                                    {445                                        cachedAppDomainNames = new List<string>(processDebugPreference.AppDomainNames);446 447                                        foreach (string currentAppDomainName in appDomainName)448                                        {449                                            if (!cachedAppDomainNames.Contains(currentAppDomainName, StringComparer.OrdinalIgnoreCase))450                                            {451                                                cachedAppDomainNames.Add(currentAppDomainName);452                                                iscacheUpdated = true;453                                            }454                                        }455                                    }456 457                                    if (iscacheUpdated)458                                    {459                                        DebugPreference DebugPreference = CreateDebugPreference(cachedAppDomainNames.ToArray());460                                        debugPreferenceCache[processName] = DebugPreference;461                                    }462                                }463                            }464                        }465                        else466                        {467                            // Debug preference is set to disable.468                            if (debugPreferenceCache.ContainsKey(processName))469                            {470                                if (appDomainName == null)471                                {472                                    debugPreferenceCache.Remove(processName);473                                    iscacheUpdated = true;474                                }475                                else476                                {477                                    DebugPreference processDebugPreference = GetProcessSpecificDebugPreference(debugPreferenceCache[processName]);478 479                                    // processDebugPreference would point to null if debug preference is enabled for all app domains.480                                    // If processDebugPreference is not null then it means that user has selected specific481                                    // appdomins for which the debug preference has to be enabled.482                                    if (processDebugPreference != null)483                                    {484                                        List<string> cachedAppDomainNames = null;485                                        if (processDebugPreference.AppDomainNames != null && processDebugPreference.AppDomainNames.Length > 0)486                                        {487                                            cachedAppDomainNames = new List<string>(processDebugPreference.AppDomainNames);488 489                                            foreach (string currentAppDomainName in appDomainName)490                                            {491                                                if (cachedAppDomainNames.Contains(currentAppDomainName, StringComparer.OrdinalIgnoreCase))492                                                {493                                                    // remove requested appdomains debug preference details.494                                                    cachedAppDomainNames.Remove(currentAppDomainName);495                                                    iscacheUpdated = true;496                                                }497                                            }498                                        }499 500                                        if (iscacheUpdated)501                                        {502                                            DebugPreference DebugPreference = CreateDebugPreference(cachedAppDomainNames.ToArray());503                                            debugPreferenceCache[processName] = DebugPreference;504                                        }505                                    }506                                }507                            }508                        }509                    }510                    else511                    {512                        // For whatever reason, cache is corrupted. Hence override the cache content.513                        if (enable)514                        {515                            debugPreferenceCache = new Hashtable();516                            DebugPreference DebugPreference = CreateDebugPreference(appDomainNames);517                            debugPreferenceCache.Add(processName, DebugPreference);518                            iscacheUpdated = true;519                        }520                    }521                }522 523                if (iscacheUpdated)524                {525                    using (PowerShell ps = PowerShell.Create())526                    {527                        ps.AddCommand("Export-Clixml").AddParameter("Path", LocalRunspace.s_debugPreferenceCachePath).AddParameter("InputObject", debugPreferenceCache);528                        ps.Invoke();529                    }530                }531            }532        }533 534        /// <summary>535        /// GetDebugPreferenceCache is a helper method used to fetch536        /// the debug preference cache contents as a Hashtable.537        /// </summary>538        /// <param name="runspace">Runspace.</param>539        /// <returns>If the Debug preference is persisted then a hashtable containing540        /// the debug preference is returned or else Null is returned.</returns>541        private static Hashtable GetDebugPreferenceCache(Runspace runspace)542        {543            Hashtable debugPreferenceCache = null;544            using (PowerShell ps = PowerShell.Create())545            {546                if (runspace != null)547                {548                    ps.Runspace = runspace;549                }550 551                ps.AddCommand("Import-Clixml").AddParameter("Path", LocalRunspace.s_debugPreferenceCachePath);552                Collection<PSObject> psObjects = ps.Invoke();553 554                if (psObjects != null && psObjects.Count == 1)555                {556                    debugPreferenceCache = psObjects[0].BaseObject as Hashtable;557                }558            }559 560            return debugPreferenceCache;561        }562 563        /// <summary>564        /// GetProcessSpecificDebugPreference is a helper method used to fetch persisted process specific debug preference.565        /// </summary>566        /// <param name="debugPreference"></param>567        /// <returns></returns>568        private static DebugPreference GetProcessSpecificDebugPreference(object debugPreference)569        {570            DebugPreference processDebugPreference = null;571            if (debugPreference != null)572            {573                PSObject debugPreferencePsObject = debugPreference as PSObject;574                if (debugPreferencePsObject != null)575                {576                    processDebugPreference = LanguagePrimitives.ConvertTo<DebugPreference>(debugPreferencePsObject);577                }578            }579 580            return processDebugPreference;581        }582 583        #endregion584 585        /// <summary>586        /// Open the runspace.587        /// </summary>588        /// <param name="syncCall">589        /// parameter which control if Open is done synchronously or asynchronously590        /// </param>591        protected override void OpenHelper(bool syncCall)592        {593            if (syncCall)594            {595                // Open runspace synchronously596                DoOpenHelper();597            }598            else599            {600                // Open runspace in another thread601                Thread asyncThread = new Thread(new ThreadStart(this.OpenThreadProc));602 603                asyncThread.Start();604            }605        }606 607        /// <summary>608        /// Start method for asynchronous open.609        /// </summary>610        private void OpenThreadProc()611        {612#pragma warning disable 56500613            try614            {615                DoOpenHelper();616            }617            catch (Exception)618            {619                // This exception is reported by raising RunspaceState620                // change event.621            }622#pragma warning restore 56500623        }624 625        /// <summary>626        /// Helper function used for opening a runspace.627        /// </summary>628        private void DoOpenHelper()629        {630            Dbg.Assert(InitialSessionState != null, "InitialSessionState should not be null");631            // NTRAID#Windows Out Of Band Releases-915851-2005/09/13632            if (_disposed)633            {634                throw PSTraceSource.NewObjectDisposedException("runspace");635            }636 637            bool startLifeCycleEventWritten = false;638            s_runspaceInitTracer.WriteLine("begin open runspace");639            try640            {641                _transcriptionData = new TranscriptionData();642 643                // All ISS-based configuration of the engine itself is done by AutomationEngine,644                // which calls InitialSessionState.Bind(). Anything that doesn't645                // require an active and open runspace should be done in ISS.Bind()646                _engine = new AutomationEngine(Host, InitialSessionState);647                _engine.Context.CurrentRunspace = this;648 649                // Log engine for start of engine life650                MshLog.LogEngineLifecycleEvent(_engine.Context, EngineState.Available);651                startLifeCycleEventWritten = true;652 653                _history = new History(_engine.Context);654                _jobRepository = new JobRepository();655                _jobManager = new JobManager();656                _runspaceRepository = new RunspaceRepository();657 658                s_runspaceInitTracer.WriteLine("initializing built-in aliases and variable information");659                InitializeDefaults();660            }661            catch (Exception exception)662            {663                s_runspaceInitTracer.WriteLine("Runspace open failed");664 665                // Log engine health event666                LogEngineHealthEvent(exception);667 668                // Log engine for end of engine life669                if (startLifeCycleEventWritten)670                {671                    Dbg.Assert(_engine.Context != null, "if startLifeCycleEventWritten is true, ExecutionContext must be present");672                    MshLog.LogEngineLifecycleEvent(_engine.Context, EngineState.Stopped);673                }674 675                // Open failed. Set the RunspaceState to Broken.676                SetRunspaceState(RunspaceState.Broken, exception);677 678                // Raise the event679                RaiseRunspaceStateEvents();680 681                // Rethrow the exception. For asynchronous execution,682                // OpenThreadProc will catch it. For synchronous execution683                // caller of open will catch it.684                throw;685            }686 687            SetRunspaceState(RunspaceState.Opened);688            RunspaceOpening.Set();689 690            // Raise the event691            RaiseRunspaceStateEvents();692            s_runspaceInitTracer.WriteLine("runspace opened successfully");693 694            // Now do initial state configuration that requires an active runspace695            Exception initError = InitialSessionState.BindRunspace(this, s_runspaceInitTracer);696            if (initError != null)697            {698                // Log engine health event699                LogEngineHealthEvent(initError);700 701                // Log engine for end of engine life702                Debug.Assert(_engine.Context != null,703                            "if startLifeCycleEventWritten is true, ExecutionContext must be present");704                MshLog.LogEngineLifecycleEvent(_engine.Context, EngineState.Stopped);705 706                // Open failed. Set the RunspaceState to Broken.707                SetRunspaceState(RunspaceState.Broken, initError);708 709                // Raise the event710                RaiseRunspaceStateEvents();711 712                // Throw the exception. For asynchronous execution,713                // OpenThreadProc will catch it. For synchronous execution714                // caller of open will catch it.715                throw initError;716            }717 718#if LEGACYTELEMETRY719            TelemetryAPI.ReportLocalSessionCreated(InitialSessionState, TranscriptionData);720#endif721        }722 723        /// <summary>724        /// Logs engine health event.725        /// </summary>726        internal void LogEngineHealthEvent(Exception exception)727        {728            LogEngineHealthEvent(729                exception,730                Severity.Error,731                MshLog.EVENT_ID_CONFIGURATION_FAILURE,732                null);733        }734 735        /// <summary>736        /// Logs engine health event.737        /// </summary>738        internal void LogEngineHealthEvent(Exception exception,739                             Severity severity,740                             int id,741                             Dictionary<string, string> additionalInfo)742        {743            Dbg.Assert(exception != null, "Caller should validate the parameter");744 745            LogContext logContext = new LogContext();746            logContext.EngineVersion = Version.ToString();747            logContext.HostId = Host.InstanceId.ToString();748            logContext.HostName = Host.Name;749            logContext.HostVersion = Host.Version.ToString();750            logContext.RunspaceId = InstanceId.ToString();751            logContext.Severity = severity.ToString();752            logContext.ShellId = Utils.DefaultPowerShellShellID;753            MshLog.LogEngineHealthEvent(754                logContext,755                id,756                exception,757                additionalInfo);758        }759 760        /// <summary>761        /// Returns the thread that must be used to execute pipelines when CreateThreadOptions is ReuseThread.762        /// </summary>763        /// <remarks>764        /// The pipeline calls this function after ensuring there is a single thread in the pipeline, so no locking is necessary765        /// </remarks>766        internal PipelineThread GetPipelineThread()767        {768            _pipelineThread ??= new PipelineThread(this.ApartmentState);769 770            return _pipelineThread;771        }772 773        private PipelineThread _pipelineThread = null;774 775        protected override void CloseHelper(bool syncCall)776        {777            if (syncCall)778            {779                // Do close synchronously780                DoCloseHelper();781            }782            else783            {784                // Do close asynchronously785                Thread asyncThread = new Thread(new ThreadStart(this.CloseThreadProc));786 787                asyncThread.Start();788            }789        }790 791        /// <summary>792        /// Start method for asynchronous close.793        /// </summary>794        private void CloseThreadProc()795        {796#pragma warning disable 56500797            try798            {799                DoCloseHelper();800            }801            catch (Exception)802            {803            }804#pragma warning restore 56500805        }806 807        /// <summary>808        /// Close the runspace.809        /// </summary>810        /// <remarks>811        /// Attempts to create/execute pipelines after a call to812        /// close will fail.813        /// </remarks>814        private void DoCloseHelper()815        {816            var isPrimaryRunspace = (Runspace.PrimaryRunspace == this);817            var haveOpenRunspaces = false;818            foreach (Runspace runspace in RunspaceList)819            {820                if (runspace.RunspaceStateInfo.State == RunspaceState.Opened)821                {822                    haveOpenRunspaces = true;823                    break;824                }825            }826 827            // When closing the primary runspace, ensure all other local runspaces are closed.828            var closeAllOpenRunspaces = isPrimaryRunspace && haveOpenRunspaces;829 830            // Stop all transcriptions and un-initialize AMSI if we're the last runspace to exit or we are exiting the primary runspace.831            if (!haveOpenRunspaces)832            {833                ExecutionContext executionContext = this.GetExecutionContext;834                if (executionContext != null)835                {836                    PSHostUserInterface hostUI = executionContext.EngineHostInterface.UI;837                    hostUI?.StopAllTranscribing();838                }839 840                AmsiUtils.Uninitialize();841            }842 843            // Generate the shutdown event844            Events?.GenerateEvent(PSEngineEvent.Exiting, null, Array.Empty<object>(), null, true, false);845 846            // Stop all running pipelines847            // Note:Do not perform the Cancel in lock. Reason is848            // Pipeline executes in separate thread, say threadP.849            // When pipeline is canceled/failed/completed in850            // Pipeline.ExecuteThreadProc it removes the pipeline851            // from the list of running pipelines. threadP will need852            // lock to remove the pipelines from the list of running pipelines853            // And we will deadlock.854            // Note:It is possible that one or more pipelines in the list855            // of active pipelines have completed before we call cancel.856            // That is fine since Pipeline.Cancel handles that( It ignores857            // the cancel request if pipeline execution has already858            // completed/failed/canceled.859            StopPipelines();860 861            // Disconnect all disconnectable jobs in the job repository.862            StopOrDisconnectAllJobs();863 864            // Close or disconnect all the remote runspaces available in the865            // runspace repository.866            CloseOrDisconnectAllRemoteRunspaces(() =>867                {868                    List<RemoteRunspace> runspaces = new List<RemoteRunspace>();869                    foreach (PSSession psSession in this.RunspaceRepository.Runspaces)870                    {871                        runspaces.Add(psSession.Runspace as RemoteRunspace);872                    }873 874                    return runspaces;875                });876 877            // Notify Engine components that runspace is closing.878            _engine.Context.RunspaceClosingNotification();879 880            // Log engine lifecycle event.881            MshLog.LogEngineLifecycleEvent(_engine.Context, EngineState.Stopped);882 883            // All pipelines have been canceled. Close the runspace.884            _engine = null;885 886            SetRunspaceState(RunspaceState.Closed);887 888            // Raise Event889            RaiseRunspaceStateEvents();890 891            if (closeAllOpenRunspaces)892            {893                foreach (Runspace runspace in RunspaceList)894                {895                    if (runspace.RunspaceStateInfo.State == RunspaceState.Opened)896                    {897                        runspace.Dispose();898                    }899                }900            }901 902            // Report telemetry if we have no more open runspaces.903#if LEGACYTELEMETRY904            bool allRunspacesClosed = true;905            bool hostProvidesExitTelemetry = false;906            foreach (var r in Runspace.RunspaceList)907            {908                if (r.RunspaceStateInfo.State != RunspaceState.Closed)909                {910                    allRunspacesClosed = false;911                    break;912                }913 914                var localRunspace = r as LocalRunspace;915                if (localRunspace != null && localRunspace.Host is IHostProvidesTelemetryData)916                {917                    hostProvidesExitTelemetry = true;918                    break;919                }920            }921 922            if (allRunspacesClosed && !hostProvidesExitTelemetry)923            {924                TelemetryAPI.ReportExitTelemetry(null);925            }926#endif927        }928 929        /// <summary>930        /// Closes or disconnects all the remote runspaces passed in by the getRunspace931        /// function.  If a remote runspace supports disconnect then it will be disconnected932        /// rather than closed.933        /// </summary>934        private static void CloseOrDisconnectAllRemoteRunspaces(Func<List<RemoteRunspace>> getRunspaces)935        {936            List<RemoteRunspace> runspaces = getRunspaces();937            if (runspaces.Count == 0)938            {939                return;940            }941 942            // whether the close of all remoterunspaces completed943            using (ManualResetEvent remoteRunspaceCloseCompleted = new ManualResetEvent(false))944            {945                ThrottleManager throttleManager = new ThrottleManager();946                throttleManager.ThrottleComplete += (object sender, EventArgs e) => remoteRunspaceCloseCompleted.Set();947 948                foreach (RemoteRunspace remoteRunspace in runspaces)949                {950                    IThrottleOperation operation = new CloseOrDisconnectRunspaceOperationHelper(remoteRunspace);951                    throttleManager.AddOperation(operation);952                }953 954                throttleManager.EndSubmitOperations();955 956                remoteRunspaceCloseCompleted.WaitOne();957            }958        }959 960        /// <summary>961        /// Disconnects all disconnectable jobs listed in the JobRepository.962        /// </summary>963        private void StopOrDisconnectAllJobs()964        {965            if (JobRepository.Jobs.Count == 0)966            {967                return;968            }969 970            List<RemoteRunspace> disconnectRunspaces = new List<RemoteRunspace>();971 972            using (ManualResetEvent jobsStopCompleted = new ManualResetEvent(false))973            {974                ThrottleManager throttleManager = new ThrottleManager();975                throttleManager.ThrottleComplete += (object sender, EventArgs e) => jobsStopCompleted.Set();976 977                foreach (Job job in this.JobRepository.Jobs)978                {979                    // Only stop or disconnect PowerShell jobs.980                    if (job is not PSRemotingJob)981                    {982                        continue;983                    }984 985                    if (!job.CanDisconnect)986                    {987                        // If the job cannot be disconnected then add it to988                        // the stop list.989                        throttleManager.AddOperation(new StopJobOperationHelper(job));990                    }991                    else if (job.JobStateInfo.State == JobState.Running)992                    {993                        // Otherwise add disconnectable runspaces to list so that994                        // they can be disconnected.995                        IEnumerable<RemoteRunspace> jobRunspaces = job.GetRunspaces();996                        if (jobRunspaces != null)997                        {998                            disconnectRunspaces.AddRange(jobRunspaces);999                        }1000                    }1001                }1002 1003                // Stop jobs.1004                throttleManager.EndSubmitOperations();1005                jobsStopCompleted.WaitOne();1006            }1007 1008            // Disconnect all disconnectable job runspaces found.1009            CloseOrDisconnectAllRemoteRunspaces(() => disconnectRunspaces);1010        }1011 1012        internal void ReleaseDebugger()1013        {1014            Debugger debugger = Debugger;1015            if (debugger != null)1016            {1017                try1018                {1019                    if (debugger.UnhandledBreakpointMode == UnhandledBreakpointProcessingMode.Wait)1020                    {1021                        // Sets the mode and also releases a held debug stop.1022                        debugger.UnhandledBreakpointMode = UnhandledBreakpointProcessingMode.Ignore;1023                    }1024                }1025                catch (PSNotImplementedException) { }1026            }1027        }1028 1029        #region SessionStateProxy1030 1031        protected override void DoSetVariable(string name, object value)1032        {1033            // NTRAID#Windows Out Of Band Releases-915851-2005/09/131034            if (_disposed)1035            {1036                throw PSTraceSource.NewObjectDisposedException("runspace");1037            }1038 1039            _engine.Context.EngineSessionState.SetVariableValue(name, value, CommandOrigin.Internal);1040        }1041 1042        protected override object DoGetVariable(string name)1043        {1044            // NTRAID#Windows Out Of Band Releases-915851-2005/09/131045            if (_disposed)1046            {1047                throw PSTraceSource.NewObjectDisposedException("runspace");1048            }1049 1050            return _engine.Context.EngineSessionState.GetVariableValue(name);1051        }1052 1053        protected override List<string> DoApplications1054        {1055            get1056            {1057                if (_disposed)1058                {1059                    throw PSTraceSource.NewObjectDisposedException("runspace");1060                }1061 1062                return _engine.Context.EngineSessionState.Applications;1063            }1064        }1065 1066        protected override List<string> DoScripts1067        {1068            get1069            {1070                if (_disposed)1071                {1072                    throw PSTraceSource.NewObjectDisposedException("runspace");1073                }1074 1075                return _engine.Context.EngineSessionState.Scripts;1076            }1077        }1078 1079        protected override DriveManagementIntrinsics DoDrive1080        {1081            get1082            {1083                if (_disposed)1084                {1085                    throw PSTraceSource.NewObjectDisposedException("runspace");1086                }1087 1088                return _engine.Context.SessionState.Drive;1089            }1090        }1091 1092        protected override PSLanguageMode DoLanguageMode1093        {1094            get1095            {1096                if (_disposed)1097                {1098                    throw PSTraceSource.NewObjectDisposedException("runspace");1099                }1100 1101                return _engine.Context.SessionState.LanguageMode;1102            }1103 1104            set1105            {1106                if (_disposed)1107                {1108                    throw PSTraceSource.NewObjectDisposedException("runspace");1109                }1110 1111                _engine.Context.SessionState.LanguageMode = value;1112            }1113        }1114 1115        protected override PSModuleInfo DoModule1116        {1117            get1118            {1119                if (_disposed)1120                {1121                    throw PSTraceSource.NewObjectDisposedException("runspace");1122                }1123 1124                return _engine.Context.EngineSessionState.Module;1125            }1126        }1127 1128        protected override PathIntrinsics DoPath1129        {1130            get1131            {1132                if (_disposed)1133                {1134                    throw PSTraceSource.NewObjectDisposedException("runspace");1135                }1136 1137                return _engine.Context.SessionState.Path;1138            }1139        }1140 1141        protected override CmdletProviderManagementIntrinsics DoProvider1142        {1143            get1144            {1145                if (_disposed)1146                {1147                    throw PSTraceSource.NewObjectDisposedException("runspace");1148                }1149 1150                return _engine.Context.SessionState.Provider;1151            }1152        }1153 1154        protected override PSVariableIntrinsics DoPSVariable1155        {1156            get1157            {1158                if (_disposed)1159                {1160                    throw PSTraceSource.NewObjectDisposedException("runspace");1161                }1162 1163                return _engine.Context.SessionState.PSVariable;1164            }1165        }1166 1167        protected override CommandInvocationIntrinsics DoInvokeCommand1168        {1169            get1170            {1171                if (_disposed)1172                {1173                    throw PSTraceSource.NewObjectDisposedException("runspace");1174                }1175 1176                return _engine.Context.EngineIntrinsics.InvokeCommand;1177            }1178        }1179 1180        protected override ProviderIntrinsics DoInvokeProvider1181        {1182            get1183            {1184                if (_disposed)1185                {1186                    throw PSTraceSource.NewObjectDisposedException("runspace");1187                }1188 1189                return _engine.Context.EngineIntrinsics.InvokeProvider;1190            }1191        }1192 1193        #endregion SessionStateProxy1194 1195        #region IDisposable Members1196 1197        /// <summary>1198        /// Set to true when object is disposed.1199        /// </summary>1200        private bool _disposed;

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