Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
Connection.cs1902 linesDownload Raw Back to hostifaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Collections.ObjectModel;6using System.Diagnostics.CodeAnalysis;7using System.Management.Automation.Host;8using System.Management.Automation.Internal;9using System.Runtime.Serialization;10using System.Threading;11 12using Dbg = System.Management.Automation.Diagnostics;13 14namespace System.Management.Automation.Runspaces15{16    #region Exceptions17 18    /// <summary>19    /// Exception thrown when state of the runspace is different from20    /// expected state of runspace.21    /// </summary>22    public class InvalidRunspaceStateException : SystemException23    {24        /// <summary>25        /// Initializes a new instance of InvalidRunspaceStateException.26        /// </summary>27        public InvalidRunspaceStateException()28        : base29        (30            StringUtil.Format(RunspaceStrings.InvalidRunspaceStateGeneral)31        )32        {33        }34 35        /// <summary>36        /// Initializes a new instance of InvalidRunspaceStateException with a specified error message.37        /// </summary>38        /// <param name="message">39        /// The message that describes the error.40        /// </param>41        public InvalidRunspaceStateException(string message)42        : base(message)43        {44        }45 46        /// <summary>47        /// Initializes a new instance of the InvalidRunspaceStateException class48        /// with a specified error message and a reference to the inner exception49        /// that is the cause of this exception.50        /// </summary>51        /// <param name="message">52        /// The message that describes the error.53        /// </param>54        /// <param name="innerException">55        /// The exception that is the cause of the current exception.56        /// </param>57        public InvalidRunspaceStateException(string message, Exception innerException)58        : base(message, innerException)59        {60        }61 62        /// <summary>63        /// Initializes a new instance of the InvalidRunspaceStateException64        /// with a specified error message and current and expected state.65        /// </summary>66        /// <param name="message">The message that describes the error.</param>67        /// <param name="currentState">Current state of runspace.</param>68        /// <param name="expectedState">Expected states of runspace.</param>69        internal InvalidRunspaceStateException70        (71            string message,72            RunspaceState currentState,73            RunspaceState expectedState74        )75        : base(message)76        {77            _expectedState = expectedState;78            _currentState = currentState;79        }80 81        #region ISerializable Members82 83        // 2005/04/20-JonN No need to implement GetObjectData84        // if all fields are static or [NonSerialized]85 86        /// <summary>87        /// Initializes a new instance of the <see cref="InvalidRunspaceStateException"/>88        ///  class with serialized data.89        /// </summary>90        /// <param name="info">91        /// The <see cref="SerializationInfo"/> that holds the serialized object92        /// data about the exception being thrown.93        /// </param>94        /// <param name="context">95        /// The <see cref="StreamingContext"/> that contains contextual information96        /// about the source or destination.97        /// </param>98        [Obsolete("Legacy serialization support is deprecated since .NET 8", DiagnosticId = "SYSLIB0051")]99        protected InvalidRunspaceStateException(SerializationInfo info, StreamingContext context)100        {101            throw new NotSupportedException();102        }103 104        #endregion105 106        /// <summary>107        /// Access CurrentState of the runspace.108        /// </summary>109        /// <remarks>This is the state of the runspace when exception was thrown.110        /// </remarks>111        public RunspaceState CurrentState112        {113            get114            {115                return _currentState;116            }117 118            internal set119            {120                _currentState = value;121            }122        }123 124        /// <summary>125        /// Expected state of runspace by the operation which has thrown this exception.126        /// </summary>127        public RunspaceState ExpectedState128        {129            get130            {131                return _expectedState;132            }133 134            internal set135            {136                _expectedState = value;137            }138        }139 140        /// <summary>141        /// State of the runspace when exception was thrown.142        /// </summary>143        [NonSerialized]144        private RunspaceState _currentState = 0;145 146        /// <summary>147        /// States of the runspace expected in method which throws this exception.148        /// </summary>149        [NonSerialized]150        private RunspaceState _expectedState = 0;151    }152 153    #endregion Exceptions154 155    #region Runspace state156 157    /// <summary>158    /// Defines various states of runspace.159    /// </summary>160    public enum RunspaceState161    {162        /// <summary>163        /// Beginning state upon creation.164        /// </summary>165        BeforeOpen = 0,166        /// <summary>167        /// A runspace is being established.168        /// </summary>169        Opening = 1,170        /// <summary>171        /// The runspace is established and valid.172        /// </summary>173        Opened = 2,174        /// <summary>175        /// The runspace is closed or has not been established.176        /// </summary>177        Closed = 3,178        /// <summary>179        /// The runspace is being closed.180        /// </summary>181        Closing = 4,182        /// <summary>183        /// The runspace has been disconnected abnormally.184        /// </summary>185        Broken = 5,186        /// <summary>187        /// The runspace is being disconnected.188        /// </summary>189        Disconnecting = 6,190        /// <summary>191        /// The runspace is disconnected.192        /// </summary>193        Disconnected = 7,194        /// <summary>195        /// The runspace is Connecting.196        /// </summary>197        Connecting = 8198    }199 200    /// <summary>201    /// These options control whether a new thread is created when a command is executed within a runspace.202    /// </summary>203    public enum PSThreadOptions204    {205        /// <summary>206        /// Use the default options: UseNewThread for local Runspace, ReuseThread for local RunspacePool, server settings for remote Runspace and RunspacePool.207        /// </summary>208        Default = 0,209 210        /// <summary>211        /// Creates a new thread for each invocation.212        /// </summary>213        UseNewThread = 1,214 215        /// <summary>216        /// Creates a new thread for the first invocation and then re-uses217        /// that thread in subsequent invocations.218        /// </summary>219        ReuseThread = 2,220 221        /// <summary>222        /// Doesn't create a new thread; the execution occurs on the thread223        /// that calls Invoke. This option is not valid for asynchronous calls.224        /// </summary>225        UseCurrentThread = 3226    }227 228    /// <summary>229    /// Defines type which has information about RunspaceState and230    /// Exception associated with RunspaceState.231    /// </summary>232    public sealed class RunspaceStateInfo233    {234        #region constructors235 236        /// <summary>237        /// Constructor for state changes not resulting from an error.238        /// </summary>239        /// <param name="state">The state of the runspace.</param>240        internal RunspaceStateInfo(RunspaceState state)241            : this(state, null)242        {243        }244 245        /// <summary>246        /// Constructor for state changes with an optional error.247        /// </summary>248        /// <param name="state">The state of runspace.</param>249        /// <param name="reason">A non-null exception if the state change was250        /// caused by an error, otherwise; null.251        /// </param>252        internal RunspaceStateInfo(RunspaceState state, Exception reason)253            : base()254        {255            State = state;256            Reason = reason;257        }258 259        /// <summary>260        /// Copy constructor to support cloning.261        /// </summary>262        /// <param name="runspaceStateInfo">The source263        /// RunspaceStateInfo264        /// </param>265        internal RunspaceStateInfo(RunspaceStateInfo runspaceStateInfo)266        {267            State = runspaceStateInfo.State;268            Reason = runspaceStateInfo.Reason;269        }270        #endregion constructors271 272        #region public_properties273 274        /// <summary>275        /// The state of the runspace.276        /// </summary>277        public RunspaceState State { get; }278 279        /// <summary>280        /// The reason for the state change, if caused by an error.281        /// </summary>282        /// <remarks>283        /// The value of this property is non-null if the state284        /// changed due to an error. Otherwise, the value of this285        /// property is null.286        /// </remarks>287        public Exception Reason { get; }288 289        #endregion public_properties290 291        /// <summary>292        /// Override for ToString()293        /// </summary>294        /// <returns></returns>295        public override string ToString()296        {297            return State.ToString();298        }299 300        /// <summary>301        /// Clones current object.302        /// </summary>303        /// <returns>Cloned object.</returns>304        internal RunspaceStateInfo Clone()305        {306            return new RunspaceStateInfo(this);307        }308 309        #region private_fields310 311        #endregion private_fields312    }313 314    /// <summary>315    /// Defines Event arguments passed to RunspaceStateEvent handler316    /// <see cref="Runspace.StateChanged"/> event.317    /// </summary>318    public sealed class RunspaceStateEventArgs : EventArgs319    {320        #region constructors321 322        /// <summary>323        /// Constructs RunspaceStateEventArgs using RunspaceStateInfo.324        /// </summary>325        /// <param name="runspaceStateInfo">The information about326        /// current state of the runspace.</param>327        /// <exception cref="ArgumentNullException">RunspaceStateInfo is null328        /// </exception>329        internal RunspaceStateEventArgs(RunspaceStateInfo runspaceStateInfo)330        {331            if (runspaceStateInfo == null)332            {333                throw PSTraceSource.NewArgumentNullException(nameof(runspaceStateInfo));334            }335 336            RunspaceStateInfo = runspaceStateInfo;337        }338 339        #endregion constructors340 341        #region public_properties342 343        /// <summary>344        /// Information about state of the runspace.345        /// </summary>346        /// <remarks>347        /// This value indicates the state of the runspace after the348        /// change.349        /// </remarks>350        public RunspaceStateInfo RunspaceStateInfo { get; }351 352        #endregion public_properties353    }354 355    /// <summary>356    /// Enum to indicate whether a Runspace is busy or available.357    /// </summary>358    public enum RunspaceAvailability359    {360        /// <summary>361        /// The Runspace is not been in the Opened state.362        /// </summary>363        None = 0,364 365        /// <summary>366        /// The Runspace is available to execute commands.367        /// </summary>368        Available,369 370        /// <summary>371        /// The Runspace is available to execute nested commands.372        /// </summary>373        AvailableForNestedCommand,374 375        /// <summary>376        /// The Runspace is busy executing a command.377        /// </summary>378        Busy,379 380        /// <summary>381        /// Applies only to remote runspace case.  The remote runspace382        /// is currently in a Debugger Stop mode and requires a debugger383        /// SetDebuggerAction() call to continue.384        /// </summary>385        RemoteDebug386    }387 388    /// <summary>389    /// Defines the event arguments passed to the AvailabilityChanged <see cref="Runspace.AvailabilityChanged"/> event.390    /// </summary>391    public sealed class RunspaceAvailabilityEventArgs : EventArgs392    {393        internal RunspaceAvailabilityEventArgs(RunspaceAvailability runspaceAvailability)394        {395            RunspaceAvailability = runspaceAvailability;396        }397 398        /// <summary>399        /// Whether the Runspace is available to execute commands.400        /// </summary>401        public RunspaceAvailability RunspaceAvailability { get; }402    }403 404    #endregion Runspace state405 406    #region Runspace capabilities407 408    /// <summary>409    /// Defines runspace capabilities.410    /// </summary>411    public enum RunspaceCapability412    {413        /// <summary>414        /// Legacy capabilities for WinRM only, from Win7 timeframe.415        /// </summary>416        Default = 0x0,417 418        /// <summary>419        /// Runspace and remoting layer supports disconnect/connect feature.420        /// </summary>421        SupportsDisconnect = 0x1,422 423        /// <summary>424        /// Runspace is based on a named pipe transport.425        /// </summary>426        NamedPipeTransport = 0x2,427 428        /// <summary>429        /// Runspace is based on a VM socket transport.430        /// </summary>431        VMSocketTransport = 0x4,432 433        /// <summary>434        /// Runspace is based on SSH transport.435        /// </summary>436        SSHTransport = 0x8,437 438        /// <summary>439        /// Runspace is based on open custom connection/transport support.440        /// </summary>441        CustomTransport = 0x100442    }443 444    #endregion445 446    /// <summary>447    /// Public interface to PowerShell Runtime. Provides APIs for creating pipelines,448    /// access session state etc.449    /// </summary>450    public abstract class Runspace : IDisposable451    {452        #region Private Data453 454        private static int s_globalId;455        private readonly Stack<PowerShell> _runningPowerShells;456        private PowerShell _baseRunningPowerShell;457        private readonly object _syncObject;458 459        #endregion460 461        #region constructor462 463        /// <summary>464        /// Explicit default constructor.465        /// </summary>466        internal Runspace()467        {468            // Create the default Runspace Id and friendly name.469            Id = System.Threading.Interlocked.Increment(ref s_globalId);470            Name = "Runspace" + Id.ToString(System.Globalization.NumberFormatInfo.InvariantInfo);471            _runningPowerShells = new Stack<PowerShell>();472            _syncObject = new object();473 474            // Keep track of this runspace until it is disposed.475            lock (s_syncObject)476            {477                s_runspaceDictionary.Add(Id, new WeakReference<Runspace>(this));478            }479        }480 481        /// <summary>482        /// Static Constructor.483        /// </summary>484        static Runspace()485        {486            s_syncObject = new object();487            s_runspaceDictionary = new SortedDictionary<int, WeakReference<Runspace>>();488            s_globalId = 0;489        }490 491        #endregion constructor492 493        #region properties494 495        /// <summary>496        /// Used to store Runspace reference on per thread basis. Used by497        /// various PowerShell engine features to get access to TypeTable498        /// etc.499        /// </summary>500        [ThreadStatic]501        private static Runspace t_threadSpecificDefaultRunspace = null;502        /// <summary>503        /// Gets and sets the default Runspace used to evaluate scripts.504        /// </summary>505        /// <remarks>The Runspace used to set this property should not be shared between different threads.</remarks>506        public static Runspace DefaultRunspace507        {508            get509            {510                return t_threadSpecificDefaultRunspace;511            }512 513            set514            {515                if (value == null || !value.RunspaceIsRemote)516                {517                    t_threadSpecificDefaultRunspace = value;518                }519                else520                {521                    throw new InvalidOperationException(RunspaceStrings.RunspaceNotLocal);522                }523            }524        }525 526        /// <summary>527        /// A PrimaryRunspace is a runspace that persists for the entire lifetime of the PowerShell session. It is only528        /// closed or disposed when the session is ending.  So when the PrimaryRunspace is closing it will trigger on-exit529        /// cleanup that includes closing any other local runspaces left open, and will allow the process to exit.530        /// </summary>531        internal static Runspace PrimaryRunspace532        {533            get534            {535                return s_primaryRunspace;536            }537 538            set539            {540                var result = Interlocked.CompareExchange<Runspace>(ref s_primaryRunspace, value, null);541                if (result != null)542                {543                    throw new PSInvalidOperationException(RunspaceStrings.PrimaryRunspaceAlreadySet);544                }545            }546        }547 548        private static Runspace s_primaryRunspace;549 550        /// <summary>551        /// Returns true if Runspace.DefaultRunspace can be used to552        /// create an instance of the PowerShell class with553        /// 'UseCurrentRunspace = true'.554        /// </summary>555        public static bool CanUseDefaultRunspace556        {557            // can use default runspace in a thread safe manner only if558            // 1. we have a default runspace559            // 2. we recognize the type of current runspace and current pipeline560            // 3. the pipeline executes on the same thread as this method561 562            // we don't return "true" for563            // 1. we have a default runspace564            // 2. no currently executing pipeline565            // to avoid a race condition where a pipeline is started566            // after this property getter did all the checks567 568            get569            {570                RunspaceBase runspace = Runspace.DefaultRunspace as RunspaceBase;571                if (runspace != null)572                {573                    Pipeline currentPipeline = runspace.GetCurrentlyRunningPipeline();574                    LocalPipeline localPipeline = currentPipeline as LocalPipeline;575                    if ((localPipeline != null) && (localPipeline.NestedPipelineExecutionThread != null))576                    {577                        return578                            (localPipeline.NestedPipelineExecutionThread.ManagedThreadId579                            == Environment.CurrentManagedThreadId);580                    }581                }582 583                return false;584            }585        }586 587        internal const ApartmentState DefaultApartmentState = ApartmentState.Unknown;588 589        /// <summary>590        /// ApartmentState of the thread used to execute commands within this Runspace.591        /// </summary>592        /// <remarks>593        /// Any updates to the value of this property must be done before the Runspace is opened594        /// </remarks>595        /// <exception cref="InvalidRunspaceStateException">596        /// An attempt to change this property was made after opening the Runspace597        /// </exception>598        public ApartmentState ApartmentState599        {600            get601            {602                return this.apartmentState;603            }604 605            set606            {607                if (this.RunspaceStateInfo.State != RunspaceState.BeforeOpen)608                {609                    throw new InvalidRunspaceStateException(StringUtil.Format(RunspaceStrings.ChangePropertyAfterOpen));610                }611 612                this.apartmentState = value;613            }614        }615 616        private ApartmentState apartmentState = Runspace.DefaultApartmentState;617 618        /// <summary>619        /// This property determines whether a new thread is create for each invocation.620        /// </summary>621        /// <remarks>622        /// Any updates to the value of this property must be done before the Runspace is opened623        /// </remarks>624        /// <exception cref="InvalidRunspaceStateException">625        /// An attempt to change this property was made after opening the Runspace626        /// </exception>627        /// <exception cref="InvalidOperationException">628        /// The thread options cannot be changed to the requested value629        /// </exception>630        public abstract PSThreadOptions ThreadOptions631        {632            get;633            set;634        }635 636        /// <summary>637        /// Return version of this runspace.638        /// </summary>639        public abstract Version Version640        {641            get;642        }643 644        /// <summary>645        /// Return whether the Runspace is Remote646        /// We can determine this by whether the runspace is an implementation of LocalRunspace647        /// or infer it from whether the ConnectionInfo property is null648        /// If it happens to be an instance of a LocalRunspace, but has a non-null ConnectionInfo649        /// we declare it to be remote.650        /// </summary>651        public bool RunspaceIsRemote652        {653            get654            {655                return this is not LocalRunspace && ConnectionInfo != null;656            }657        }658 659        /// <summary>660        /// Retrieve information about current state of the runspace.661        /// </summary>662        public abstract RunspaceStateInfo RunspaceStateInfo663        {664            get;665        }666 667        /// <summary>668        /// Gets the current availability of the Runspace.669        /// </summary>670        public abstract RunspaceAvailability RunspaceAvailability671        {672            get;673            protected set;674        }675 676        /// <summary>677        /// InitialSessionState information for this runspace.678        /// </summary>679        public abstract InitialSessionState InitialSessionState680        {681            get;682        }683 684        /// <summary>685        /// Get unique id for this instance of runspace. It is primarily used686        /// for logging purposes.687        /// </summary>688        public Guid InstanceId689        {690            get;691 692            // This id is also used to identify proxy and remote runspace objects.693            // We need to set this when reconstructing a remote runspace to connect694            // to an existing remote runspace.695            internal set;696        } = Guid.NewGuid();697 698        /// <summary>699        /// Gets execution context.700        /// </summary>701        /// <exception cref="InvalidRunspaceStateException">Runspace is not opened.702        /// </exception>703        internal ExecutionContext ExecutionContext704        {705            get706            {707                return GetExecutionContext;708            }709        }710 711        /// <summary>712        /// Skip user profile on engine initialization.713        /// </summary>714        internal bool SkipUserProfile { get; set; } = false;715 716        /// <summary>717        /// Connection information for remote Runspaces, null for local Runspaces.718        /// </summary>719        public abstract RunspaceConnectionInfo ConnectionInfo { get; }720 721        /// <summary>722        /// ConnectionInfo originally supplied by the user.723        /// </summary>724        public abstract RunspaceConnectionInfo OriginalConnectionInfo { get; }725 726        /// <summary>727        /// Manager for JobSourceAdapters registered in this runspace.728        /// </summary>729        public abstract JobManager JobManager { get; }730 731        /// <summary>732        /// DisconnectedOn property applies to remote runspaces that have733        /// been disconnected.734        /// </summary>735        public DateTime? DisconnectedOn736        {737            get;738            internal set;739        }740 741        /// <summary>742        /// ExpiresOn property applies to remote runspaces that have been743        /// disconnected.744        /// </summary>745        public DateTime? ExpiresOn746        {747            get;748            internal set;749        }750 751        /// <summary>752        /// Gets and sets a friendly name for the Runspace.753        /// </summary>754        public string Name755        {756            get;757            set;758        }759 760        /// <summary>761        /// Gets the Runspace Id.762        /// </summary>763        public int Id { get; }764        765        /// <summary>766        /// Gets and sets a boolean indicating whether the runspace has a767        /// debugger attached with <c>Debug-Runspace</c>.768        /// </summary>769        public bool IsRemoteDebuggerAttached { get; internal set; }770 771        /// <summary>772        /// Returns protocol version that the remote server uses for PS remoting.773        /// </summary>774        internal Version GetRemoteProtocolVersion()775        {776            Version remoteProtocolVersionDeclaredByServer;777            bool isServerDeclarationValid = PSPrimitiveDictionary.TryPathGet(778                this.GetApplicationPrivateData(),779                out remoteProtocolVersionDeclaredByServer,780                PSVersionInfo.PSVersionTableName,781                PSVersionInfo.PSRemotingProtocolVersionName);782 783            if (isServerDeclarationValid)784            {785                return remoteProtocolVersionDeclaredByServer;786            }787            else788            {789                return RemotingConstants.ProtocolVersion;790            }791        }792 793        /// <summary>794        /// Engine activity id (for ETW tracing)795        /// </summary>796        internal Guid EngineActivityId { get; set; } = Guid.Empty;797 798        /// <summary>799        /// Returns a read only runspace dictionary.800        /// </summary>801        internal static ReadOnlyDictionary<int, WeakReference<Runspace>> RunspaceDictionary802        {803            get804            {805                lock (s_syncObject)806                {807                    return new ReadOnlyDictionary<int, WeakReference<Runspace>>(new Dictionary<int, WeakReference<Runspace>>(s_runspaceDictionary));808                }809            }810        }811 812        private static readonly SortedDictionary<int, WeakReference<Runspace>> s_runspaceDictionary;813        private static readonly object s_syncObject;814 815        /// <summary>816        /// Returns a read only list of runspaces.817        /// </summary>818        internal static IReadOnlyList<Runspace> RunspaceList819        {820            get821            {822                List<Runspace> runspaceList = new List<Runspace>();823 824                lock (s_syncObject)825                {826                    foreach (var item in s_runspaceDictionary.Values)827                    {828                        Runspace runspace;829                        if (item.TryGetTarget(out runspace))830                        {831                            runspaceList.Add(runspace);832                        }833                    }834                }835 836                return new ReadOnlyCollection<Runspace>(runspaceList);837            }838        }839 840        #endregion properties841 842        #region events843 844        /// <summary>845        /// Event raised when RunspaceState changes.846        /// </summary>847        public abstract event EventHandler<RunspaceStateEventArgs> StateChanged;848 849        /// <summary>850        /// Event raised when the availability of the Runspace changes.851        /// </summary>852        public abstract event EventHandler<RunspaceAvailabilityEventArgs> AvailabilityChanged;853 854        /// <summary>855        /// Returns true if there are any subscribers to the AvailabilityChanged event.856        /// </summary>857        internal abstract bool HasAvailabilityChangedSubscribers858        {859            get;860        }861 862        /// <summary>863        /// Raises the AvailabilityChanged event.864        /// </summary>865        protected abstract void OnAvailabilityChanged(RunspaceAvailabilityEventArgs e);866 867        /// <summary>868        /// Used to raise the AvailabilityChanged event when the state of the currently executing pipeline changes.869        /// </summary>870        /// <remarks>871        /// The possible pipeline states are872        ///     NotStarted873        ///     Running874        ///     Disconnected875        ///     Stopping876        ///     Stopped877        ///     Completed878        ///     Failed879        /// </remarks>880        internal void UpdateRunspaceAvailability(PipelineState pipelineState, bool raiseEvent, Guid? cmdInstanceId = null)881        {882            RunspaceAvailability oldAvailability = this.RunspaceAvailability;883 884            switch (oldAvailability)885            {886                // Because of disconnect/connect support runspace availability can now transition887                // in and out of "None" state.888                case RunspaceAvailability.None:889                    switch (pipelineState)890                    {891                        case PipelineState.Running:892                            this.RunspaceAvailability = RunspaceAvailability.Busy;893                            break;894 895                            // Otherwise no change.896                    }897 898                    break;899 900                case RunspaceAvailability.Available:901                    switch (pipelineState)902                    {903                        case PipelineState.Running:904                            this.RunspaceAvailability = RunspaceAvailability.Busy;905                            break;906 907                        case PipelineState.Disconnected:908                            this.RunspaceAvailability = Runspaces.RunspaceAvailability.None;909                            break;910                    }911 912                    break;913 914                case RunspaceAvailability.AvailableForNestedCommand:915                    switch (pipelineState)916                    {917                        case PipelineState.Running:918                            this.RunspaceAvailability = RunspaceAvailability.Busy;919                            break;920 921                        case PipelineState.Completed: // a nested pipeline caused the host to exit nested prompt922                            this.RunspaceAvailability = (this.InNestedPrompt || (_runningPowerShells.Count > 1)) ?923                                RunspaceAvailability.AvailableForNestedCommand : RunspaceAvailability.Available;924                            break;925 926                        default:927                            break; // no change in the availability928                    }929 930                    break;931 932                case RunspaceAvailability.Busy:933                case RunspaceAvailability.RemoteDebug:934                    switch (pipelineState)935                    {936                        case PipelineState.Disconnected:937                            if (oldAvailability == Runspaces.RunspaceAvailability.RemoteDebug)938                            {939                                this.RunspaceAvailability = RunspaceAvailability.RemoteDebug;940                            }941                            else942                            {943                                this.RunspaceAvailability = RunspaceAvailability.None;944                            }945 946                            break;947 948                        case PipelineState.Stopping:949                            break; // no change in the availability950 951                        case PipelineState.Completed:952                        case PipelineState.Stopped:953                        case PipelineState.Failed:954                            if (this.InNestedPrompt955                                || (this is not RemoteRunspace && this.Debugger.InBreakpoint))956                            {957                                this.RunspaceAvailability = RunspaceAvailability.AvailableForNestedCommand;958                            }959                            else960                            {961                                RemoteRunspace remoteRunspace = this as RemoteRunspace;962                                RemoteDebugger remoteDebugger = (remoteRunspace != null) ? remoteRunspace.Debugger as RemoteDebugger : null;963                                Internal.ConnectCommandInfo remoteCommand = remoteRunspace?.RemoteCommand;964                                if (((pipelineState == PipelineState.Completed) || (pipelineState == PipelineState.Failed) ||965                                    ((pipelineState == PipelineState.Stopped) && (this.RunspaceStateInfo.State == RunspaceState.Opened)))966                                    && (remoteCommand != null) && (cmdInstanceId != null) && (remoteCommand.CommandId == cmdInstanceId))967                                {968                                    // Completed, Failed, and Stopped with Runspace.Opened states are command finish states and we know969                                    // that the command is finished on the server.970                                    // Setting ConnectCommands to null indicates that the runspace is free to run other971                                    // commands.972                                    remoteRunspace.RunspacePool.RemoteRunspacePoolInternal.ConnectCommands = null;973                                    remoteCommand = null;974 975                                    if ((remoteDebugger != null) && (pipelineState == PipelineState.Stopped))976                                    {977                                        // Notify remote debugger of a stop in case the stop occurred while command was in debug stop.978                                        remoteDebugger.OnCommandStopped();979                                    }980                                }981 982                                Pipeline currentPipeline = this.GetCurrentlyRunningPipeline();983                                RemotePipeline remotePipeline = currentPipeline as RemotePipeline;984                                Guid? pipeLineCmdInstance = (remotePipeline != null && remotePipeline.PowerShell != null) ? remotePipeline.PowerShell.InstanceId : (Guid?)null;985                                if (currentPipeline == null)986                                {987                                    // A runspace is available:988                                    //  - if there is no currently running pipeline989                                    //    and for remote runspaces:990                                    //    - if there is no remote command associated with it.991                                    //    - if the remote runspace pool is marked as available for connection.992                                    if (remoteCommand == null)993                                    {994                                        if (remoteRunspace != null)995                                        {996                                            if ((remoteDebugger != null) && (pipelineState == PipelineState.Stopped))997                                            {998                                                // Notify remote debugger of a stop in case the stop occurred while command was in debug stop.999                                                remoteDebugger.OnCommandStopped();1000                                            }1001 1002                                            this.RunspaceAvailability =1003                                                remoteRunspace.RunspacePool.RemoteRunspacePoolInternal.AvailableForConnection ?1004                                                RunspaceAvailability.Available : Runspaces.RunspaceAvailability.Busy;1005                                        }1006                                        else1007                                        {1008                                            this.RunspaceAvailability = RunspaceAvailability.Available;1009                                        }1010                                    }1011                                }1012                                else if ((cmdInstanceId != null) && (pipeLineCmdInstance != null) && (cmdInstanceId == pipeLineCmdInstance))1013                                {1014                                    if ((remoteDebugger != null) && (pipelineState == PipelineState.Stopped))1015                                    {1016                                        // Notify remote debugger of a stop in case the stop occurred while command was in debug stop.1017                                        remoteDebugger.OnCommandStopped();1018                                    }1019 1020                                    this.RunspaceAvailability = RunspaceAvailability.Available;1021                                }1022                                else // a nested pipeline completed, but the parent pipeline is still running1023                                {1024                                    if (oldAvailability == Runspaces.RunspaceAvailability.RemoteDebug)1025                                    {1026                                        this.RunspaceAvailability = Runspaces.RunspaceAvailability.RemoteDebug;1027                                    }1028                                    else if ((currentPipeline.PipelineStateInfo.State == PipelineState.Running) || (_runningPowerShells.Count > 1))1029                                    {1030                                        // Either the current pipeline is running or there are other nested commands to run in the Runspace.1031                                        this.RunspaceAvailability = RunspaceAvailability.Busy;1032                                    }1033                                    else1034                                    {1035                                        this.RunspaceAvailability = RunspaceAvailability.Available;1036                                    }1037                                }1038                            }1039 1040                            break;1041 1042                        case PipelineState.Running: // this can happen if a nested pipeline is created without entering a nested prompt1043                            break; // no change in the availability1044 1045                        default:1046                            break; // no change in the availability1047                    }1048 1049                    break;1050 1051                default:1052                    Diagnostics.Assert(false, "Invalid RunspaceAvailability");1053                    break;1054            }1055 1056            if (raiseEvent && this.RunspaceAvailability != oldAvailability)1057            {1058                OnAvailabilityChanged(new RunspaceAvailabilityEventArgs(this.RunspaceAvailability));1059            }1060        }1061 1062        /// <summary>1063        /// Used to update the runspace availability when the state of the currently executing PowerShell instance changes.1064        /// </summary>1065        /// <remarks>1066        /// The possible invocation states are1067        ///     NotStarted1068        ///     Running1069        ///     Stopping1070        ///     Stopped1071        ///     Completed1072        ///     Failed1073        /// </remarks>1074        internal void UpdateRunspaceAvailability(PSInvocationState invocationState, bool raiseEvent, Guid cmdInstanceId)1075        {1076            switch (invocationState)1077            {1078                case PSInvocationState.NotStarted:1079                    UpdateRunspaceAvailability(PipelineState.NotStarted, raiseEvent, cmdInstanceId);1080                    break;1081 1082                case PSInvocationState.Running:1083                    UpdateRunspaceAvailability(PipelineState.Running, raiseEvent, cmdInstanceId);1084                    break;1085 1086                case PSInvocationState.Completed:1087                    UpdateRunspaceAvailability(PipelineState.Completed, raiseEvent, cmdInstanceId);1088                    break;1089 1090                case PSInvocationState.Failed:1091                    UpdateRunspaceAvailability(PipelineState.Failed, raiseEvent, cmdInstanceId);1092                    break;1093 1094                case PSInvocationState.Stopping:1095                    UpdateRunspaceAvailability(PipelineState.Stopping, raiseEvent, cmdInstanceId);1096                    break;1097 1098                case PSInvocationState.Stopped:1099                    UpdateRunspaceAvailability(PipelineState.Stopped, raiseEvent, cmdInstanceId);1100                    break;1101 1102                case PSInvocationState.Disconnected:1103                    UpdateRunspaceAvailability(PipelineState.Disconnected, raiseEvent, cmdInstanceId);1104                    break;1105 1106                default:1107                    Diagnostics.Assert(false, "Invalid PSInvocationState");1108                    break;1109            }1110        }1111 1112        /// <summary>1113        /// Used to update the runspace availability event when the state of the runspace changes.1114        /// </summary>1115        /// <remarks>1116        /// The possible runspace states are:1117        ///     BeforeOpen1118        ///     Opening1119        ///     Opened1120        ///     Closed1121        ///     Closing1122        ///     Broken1123        /// </remarks>1124        protected void UpdateRunspaceAvailability(RunspaceState runspaceState, bool raiseEvent)1125        {1126            RunspaceAvailability oldAvailability = this.RunspaceAvailability;1127            RemoteRunspace remoteRunspace = this as RemoteRunspace;1128            Internal.ConnectCommandInfo remoteCommand = null;1129            bool remoteDebug = false;1130 1131            if (remoteRunspace != null)1132            {1133                remoteCommand = remoteRunspace.RemoteCommand;1134                RemoteDebugger remoteDebugger = remoteRunspace.Debugger as RemoteDebugger;1135                remoteDebug = (remoteDebugger != null) && remoteDebugger.IsRemoteDebug;1136            }1137 1138            switch (oldAvailability)1139            {1140                case RunspaceAvailability.None:1141                    switch (runspaceState)1142                    {1143                        case RunspaceState.Opened:1144                            if (remoteDebug)1145                            {1146                                this.RunspaceAvailability = Runspaces.RunspaceAvailability.RemoteDebug;1147                            }1148                            else1149                            {1150                                this.RunspaceAvailability = (remoteCommand == null && GetCurrentlyRunningPipeline() == null) ?1151                                    RunspaceAvailability.Available : RunspaceAvailability.Busy;1152                            }1153 1154                            break;1155 1156                        default:1157                            break; // no change in the availability1158                    }1159 1160                    break;1161 1162                case RunspaceAvailability.Available:1163                case RunspaceAvailability.AvailableForNestedCommand:1164                case RunspaceAvailability.RemoteDebug:1165                case RunspaceAvailability.Busy:1166                    switch (runspaceState)1167                    {1168                        case RunspaceState.Closing:1169                        case RunspaceState.Closed:1170                        case RunspaceState.Broken:1171                        case RunspaceState.Disconnected:1172                            this.RunspaceAvailability = RunspaceAvailability.None;1173                            break;1174 1175                        default:1176                            break; // no change in the availability1177                    }1178 1179                    break;1180 1181                default:1182                    Diagnostics.Assert(false, "Invalid RunspaceAvailability");1183                    break;1184            }1185 1186            if (raiseEvent && this.RunspaceAvailability != oldAvailability)1187            {1188                OnAvailabilityChanged(new RunspaceAvailabilityEventArgs(this.RunspaceAvailability));1189            }1190        }1191 1192        /// <summary>1193        /// Used to update the runspace availability from Enter/ExitNestedPrompt and the debugger.1194        /// </summary>1195        internal void UpdateRunspaceAvailability(RunspaceAvailability availability, bool raiseEvent)1196        {1197            RunspaceAvailability oldAvailability = this.RunspaceAvailability;1198 1199            this.RunspaceAvailability = availability;1200 

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