MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.ObjectModel;5using System.Management.Automation.Internal;6using System.Management.Automation.Runspaces.Internal;7using System.Runtime.Serialization;8using System.Threading;9 10using PSHost = System.Management.Automation.Host.PSHost;11 12namespace System.Management.Automation.Runspaces13{14 #region Exceptions15 /// <summary>16 /// Exception thrown when state of the runspace pool is different from17 /// expected state of runspace pool.18 /// </summary>19 public class InvalidRunspacePoolStateException : SystemException20 {21 /// <summary>22 /// Creates a new instance of InvalidRunspacePoolStateException class.23 /// </summary>24 public InvalidRunspacePoolStateException()25 : base26 (27 StringUtil.Format(RunspacePoolStrings.InvalidRunspacePoolStateGeneral)28 )29 {30 }31 32 /// <summary>33 /// Creates a new instance of InvalidRunspacePoolStateException class.34 /// </summary>35 /// <param name="message">36 /// The error message that explains the reason for the exception.37 /// </param>38 public InvalidRunspacePoolStateException(string message)39 : base(message)40 {41 }42 43 /// <summary>44 /// Creates a new instance of InvalidRunspacePoolStateException class.45 /// </summary>46 /// <param name="message">47 /// The error message that explains the reason for the exception.48 /// </param>49 /// <param name="innerException">50 /// The exception that is the cause of the current exception.51 /// </param>52 public InvalidRunspacePoolStateException(string message, Exception innerException)53 : base(message, innerException)54 {55 }56 57 /// <summary>58 /// Initializes a new instance of the InvalidRunspacePoolStateException59 /// with a specified error message and current and expected state.60 /// </summary>61 /// <param name="message">The message that describes the error.</param>62 /// <param name="currentState">Current state of runspace pool.</param>63 /// <param name="expectedState">Expected state of the runspace pool.</param>64 internal InvalidRunspacePoolStateException65 (66 string message,67 RunspacePoolState currentState,68 RunspacePoolState expectedState69 )70 : base(message)71 {72 _expectedState = expectedState;73 _currentState = currentState;74 }75 76 #region ISerializable Members77 78 // No need to implement GetObjectData79 // if all fields are static or [NonSerialized]80 81 /// <summary>82 /// Initializes a new instance of the InvalidRunspacePoolStateException83 /// class with serialized data.84 /// </summary>85 /// <param name="info">86 /// The <see cref="SerializationInfo"/> that holds87 /// the serialized object data about the exception being thrown.88 /// </param>89 /// <param name="context">90 /// The <see cref="StreamingContext"/> that contains91 /// contextual information about the source or destination.92 /// </param>93 [Obsolete("Legacy serialization support is deprecated since .NET 8", DiagnosticId = "SYSLIB0051")]94 protected95 InvalidRunspacePoolStateException(SerializationInfo info, StreamingContext context)96 {97 throw new NotSupportedException();98 }99 100 #endregion101 102 /// <summary>103 /// Access CurrentState of the runspace pool.104 /// </summary>105 /// <remarks>106 /// This is the state of the runspace pool when exception was thrown.107 /// </remarks>108 public RunspacePoolState CurrentState109 {110 get111 {112 return _currentState;113 }114 }115 116 /// <summary>117 /// Expected state of runspace pool by the operation which has thrown118 /// this exception.119 /// </summary>120 public RunspacePoolState ExpectedState121 {122 get123 {124 return _expectedState;125 }126 }127 128 /// <summary>129 /// Converts the current to an InvalidRunspaceStateException.130 /// </summary>131 internal InvalidRunspaceStateException ToInvalidRunspaceStateException()132 {133 InvalidRunspaceStateException exception = new InvalidRunspaceStateException(134 RunspaceStrings.InvalidRunspaceStateGeneral,135 this);136 exception.CurrentState = RunspacePoolStateToRunspaceState(this.CurrentState);137 exception.ExpectedState = RunspacePoolStateToRunspaceState(this.ExpectedState);138 return exception;139 }140 141 /// <summary>142 /// Converts a RunspacePoolState to a RunspaceState.143 /// </summary>144 private static RunspaceState RunspacePoolStateToRunspaceState(RunspacePoolState state)145 {146 switch (state)147 {148 case RunspacePoolState.BeforeOpen:149 return RunspaceState.BeforeOpen;150 151 case RunspacePoolState.Opening:152 return RunspaceState.Opening;153 154 case RunspacePoolState.Opened:155 return RunspaceState.Opened;156 157 case RunspacePoolState.Closed:158 return RunspaceState.Closed;159 160 case RunspacePoolState.Closing:161 return RunspaceState.Closing;162 163 case RunspacePoolState.Broken:164 return RunspaceState.Broken;165 166 case RunspacePoolState.Disconnecting:167 return RunspaceState.Disconnecting;168 169 case RunspacePoolState.Disconnected:170 return RunspaceState.Disconnected;171 172 case RunspacePoolState.Connecting:173 return RunspaceState.Connecting;174 175 default:176 Diagnostics.Assert(false, "Unexpected RunspacePoolState");177 return 0;178 }179 }180 181 /// <summary>182 /// State of the runspace pool when exception was thrown.183 /// </summary>184 [NonSerialized]185 private readonly RunspacePoolState _currentState = 0;186 187 /// <summary>188 /// State of the runspace pool expected in method which throws this exception.189 /// </summary>190 [NonSerialized]191 private readonly RunspacePoolState _expectedState = 0;192 }193 #endregion194 195 #region State196 /// <summary>197 /// Defines various states of a runspace pool.198 /// </summary>199 public enum RunspacePoolState200 {201 /// <summary>202 /// Beginning state upon creation.203 /// </summary>204 BeforeOpen = 0,205 /// <summary>206 /// A RunspacePool is being created.207 /// </summary>208 Opening = 1,209 /// <summary>210 /// The RunspacePool is created and valid.211 /// </summary>212 Opened = 2,213 /// <summary>214 /// The RunspacePool is closed.215 /// </summary>216 Closed = 3,217 /// <summary>218 /// The RunspacePool is being closed.219 /// </summary>220 Closing = 4,221 /// <summary>222 /// The RunspacePool has been disconnected abnormally.223 /// </summary>224 Broken = 5,225 226 /// <summary>227 /// The RunspacePool is being disconnected.228 /// </summary>229 Disconnecting = 6,230 231 /// <summary>232 /// The RunspacePool has been disconnected.233 /// </summary>234 Disconnected = 7,235 236 /// <summary>237 /// The RunspacePool is being connected.238 /// </summary>239 Connecting = 8,240 }241 242 /// <summary>243 /// Event arguments passed to runspacepool state change handlers244 /// <see cref="RunspacePool.StateChanged"/> event.245 /// </summary>246 public sealed class RunspacePoolStateChangedEventArgs : EventArgs247 {248 #region Constructors249 250 /// <summary>251 /// Constructor.252 /// </summary>253 /// <param name="state">254 /// state to raise the event with.255 /// </param>256 internal RunspacePoolStateChangedEventArgs(RunspacePoolState state)257 {258 RunspacePoolStateInfo = new RunspacePoolStateInfo(state, null);259 }260 261 /// <summary>262 /// </summary>263 /// <param name="stateInfo"></param>264 internal RunspacePoolStateChangedEventArgs(RunspacePoolStateInfo stateInfo)265 {266 RunspacePoolStateInfo = stateInfo;267 }268 269 #endregion270 271 #region Public Properties272 273 /// <summary>274 /// Gets the stateinfo of RunspacePool when this event occurred.275 /// </summary>276 public RunspacePoolStateInfo RunspacePoolStateInfo { get; }277 278 #endregion279 280 #region Private Data281 282 #endregion283 }284 285 /// <summary>286 /// Event arguments passed to RunspaceCreated event of RunspacePool.287 /// </summary>288 internal sealed class RunspaceCreatedEventArgs : EventArgs289 {290 #region Private Data291 292 #endregion293 294 #region Constructors295 296 /// <summary>297 /// </summary>298 /// <param name="runspace"></param>299 internal RunspaceCreatedEventArgs(Runspace runspace)300 {301 Runspace = runspace;302 }303 304 #endregion305 306 #region Internal Properties307 308 internal Runspace Runspace { get; }309 310 #endregion311 }312 313 #endregion314 315 #region RunspacePool Availability316 317 /// <summary>318 /// Defines runspace pool availability.319 /// </summary>320 public enum RunspacePoolAvailability321 {322 /// <summary>323 /// RunspacePool is not in the Opened state.324 /// </summary>325 None = 0,326 327 /// <summary>328 /// RunspacePool is Opened and available to accept commands.329 /// </summary>330 Available = 1,331 332 /// <summary>333 /// RunspacePool on the server is connected to another334 /// client and is not available to this client for connection335 /// or running commands.336 /// </summary>337 Busy = 2338 }339 340 #endregion341 342 #region RunspacePool Capabilities343 344 /// <summary>345 /// Defines runspace capabilities.346 /// </summary>347 public enum RunspacePoolCapability348 {349 /// <summary>350 /// No additional capabilities beyond a default runspace.351 /// </summary>352 Default = 0x0,353 354 /// <summary>355 /// Runspacepool and remoting layer supports disconnect/connect feature.356 /// </summary>357 SupportsDisconnect = 0x1358 }359 360 #endregion361 362 #region AsyncResult363 364 /// <summary>365 /// Encapsulated the AsyncResult for pool's Open/Close async operations.366 /// </summary>367 internal sealed class RunspacePoolAsyncResult : AsyncResult368 {369 #region Private Data370 371 #endregion372 373 #region Constructor374 375 /// <summary>376 /// Constructor.377 /// </summary>378 /// <param name="ownerId">379 /// Instance Id of the pool creating this instance380 /// </param>381 /// <param name="callback">382 /// Callback to call when the async operation completes.383 /// </param>384 /// <param name="state">385 /// A user supplied state to call the "callback" with.386 /// </param>387 /// <param name="isCalledFromOpenAsync">388 /// true if AsyncResult monitors Async Open.389 /// false otherwise390 /// </param>391 internal RunspacePoolAsyncResult(Guid ownerId, AsyncCallback callback, object state,392 bool isCalledFromOpenAsync)393 : base(ownerId, callback, state)394 {395 IsAssociatedWithAsyncOpen = isCalledFromOpenAsync;396 }397 398 #endregion399 400 #region Internal Properties401 402 /// <summary>403 /// True if AsyncResult monitors Async Open.404 /// false otherwise.405 /// </summary>406 internal bool IsAssociatedWithAsyncOpen { get; }407 408 #endregion409 }410 411 /// <summary>412 /// Encapsulated the results of a RunspacePool.BeginGetRunspace method.413 /// </summary>414 internal sealed class GetRunspaceAsyncResult : AsyncResult415 {416 #region Private Data417 418 private bool _isActive;419 420 #endregion421 422 #region Constructor423 424 /// <summary>425 /// Constructor.426 /// </summary>427 /// <param name="ownerId">428 /// Instance Id of the pool creating this instance429 /// </param>430 /// <param name="callback">431 /// Callback to call when the async operation completes.432 /// </param>433 /// <param name="state">434 /// A user supplied state to call the "callback" with.435 /// </param>436 internal GetRunspaceAsyncResult(Guid ownerId, AsyncCallback callback, object state)437 : base(ownerId, callback, state)438 {439 _isActive = true;440 }441 442 #endregion443 444 #region Internal Methods/Properties445 446 /// <summary>447 /// Gets the runspace that is assigned to the async operation.448 /// </summary>449 /// <remarks>450 /// This can be null if the async Get operation is not completed.451 /// </remarks>452 internal Runspace Runspace { get; set; }453 454 /// <summary>455 /// Gets or sets a value indicating whether this operation456 /// is active or not.457 /// </summary>458 internal bool IsActive459 {460 get461 {462 lock (SyncObject)463 {464 return _isActive;465 }466 }467 468 set469 {470 lock (SyncObject)471 {472 _isActive = value;473 }474 }475 }476 477 /// <summary>478 /// Marks the async operation as completed and releases479 /// waiting threads.480 /// </summary>481 /// <param name="state">482 /// This is not used483 /// </param>484 /// <remarks>485 /// This method is called from a thread pool thread to release486 /// the async operation.487 /// </remarks>488 internal void DoComplete(object state)489 {490 SetAsCompleted(null);491 }492 493 #endregion494 }495 496 #endregion497 498 #region RunspacePool499 500 /// <summary>501 /// Public interface which supports pooling PowerShell Runspaces.502 /// </summary>503 public sealed class RunspacePool : IDisposable504 {505 #region Private Data506 507 private readonly RunspacePoolInternal _internalPool;508 private readonly object _syncObject = new object();509 510 private event EventHandler<RunspacePoolStateChangedEventArgs> InternalStateChanged = null;511 512 private event EventHandler<PSEventArgs> InternalForwardEvent = null;513 514 private event EventHandler<RunspaceCreatedEventArgs> InternalRunspaceCreated = null;515 516 #endregion517 518 #region Internal Constructor519 520 /// <summary>521 /// Constructor which creates a RunspacePool using the522 /// supplied <paramref name="configuration"/>,523 /// <paramref name="minRunspaces"/> and <paramref name="maxRunspaces"/>524 /// </summary>525 /// <param name="minRunspaces">526 /// The minimum number of Runspaces that can exist in this pool.527 /// Should be greater than or equal to 1.528 /// </param>529 /// <param name="maxRunspaces">530 /// The maximum number of Runspaces that can exist in this pool.531 /// Should be greater than or equal to 1.532 /// </param>533 /// <param name="host">534 /// The explicit PSHost implementation.535 /// </param>536 /// <exception cref="ArgumentNullException">537 /// Host is null.538 /// </exception>539 /// <exception cref="ArgumentException">540 /// Maximum runspaces is less than 1.541 /// Minimum runspaces is less than 1.542 /// </exception>543 internal RunspacePool(int minRunspaces, int maxRunspaces, PSHost host)544 {545 // Currently we support only Local Runspace Pool..546 // this needs to be changed once remote runspace pool547 // is implemented548 549 _internalPool = new RunspacePoolInternal(minRunspaces, maxRunspaces, host);550 }551 552 /// <summary>553 /// Constructor which creates a RunspacePool using the554 /// supplied <paramref name="initialSessionState"/>,555 /// <paramref name="minRunspaces"/> and <paramref name="maxRunspaces"/>556 /// </summary>557 /// <param name="minRunspaces">558 /// The minimum number of Runspaces that can exist in this pool.559 /// Should be greater than or equal to 1.560 /// </param>561 /// <param name="maxRunspaces">562 /// The maximum number of Runspaces that can exist in this pool.563 /// Should be greater than or equal to 1.564 /// </param>565 /// <param name="initialSessionState">566 /// InitialSessionState object to use when creating a new Runspace.567 /// </param>568 /// <param name="host">569 /// The explicit PSHost implementation.570 /// </param>571 /// <exception cref="ArgumentNullException">572 /// initialSessionState is null.573 /// Host is null.574 /// </exception>575 /// <exception cref="ArgumentException">576 /// Maximum runspaces is less than 1.577 /// Minimum runspaces is less than 1.578 /// </exception>579 internal RunspacePool(int minRunspaces, int maxRunspaces,580 InitialSessionState initialSessionState, PSHost host)581 {582 // Currently we support only Local Runspace Pool..583 // this needs to be changed once remote runspace pool584 // is implemented585 586 _internalPool = new RunspacePoolInternal(minRunspaces,587 maxRunspaces, initialSessionState, host);588 }589 590 /// <summary>591 /// Construct a runspace pool object.592 /// </summary>593 /// <param name="minRunspaces">Min runspaces.</param>594 /// <param name="maxRunspaces">Max runspaces.</param>595 /// <param name="typeTable">TypeTable.</param>596 /// <param name="host">Host.</param>597 /// <param name="applicationArguments">App arguments.</param>598 /// <param name="connectionInfo">Connection information.</param>599 /// <param name="name">Session name.</param>600 internal RunspacePool(601 int minRunspaces,602 int maxRunspaces,603 TypeTable typeTable,604 PSHost host,605 PSPrimitiveDictionary applicationArguments,606 RunspaceConnectionInfo connectionInfo,607 string name = null)608 {609 _internalPool = new RemoteRunspacePoolInternal(610 minRunspaces,611 maxRunspaces,612 typeTable,613 host,614 applicationArguments,615 connectionInfo,616 name);617 618 IsRemote = true;619 }620 621 /// <summary>622 /// Creates a runspace pool object in a disconnected state that is623 /// ready to connect to a remote runspace pool session specified by624 /// the instanceId parameter.625 /// </summary>626 /// <param name="isDisconnected">Indicates whether the shell/runspace pool is disconnected.</param>627 /// <param name="instanceId">Identifies a remote runspace pool session to connect to.</param>628 /// <param name="name">Friendly name for runspace pool.</param>629 /// <param name="connectCommands">Runspace pool running commands information.</param>630 /// <param name="connectionInfo">Connection information of remote server.</param>631 /// <param name="host">PSHost object.</param>632 /// <param name="typeTable">TypeTable used for serialization/deserialization of remote objects.</param>633 internal RunspacePool(634 bool isDisconnected,635 Guid instanceId,636 string name,637 ConnectCommandInfo[] connectCommands,638 RunspaceConnectionInfo connectionInfo,639 PSHost host,640 TypeTable typeTable)641 {642 // Disconnect-Connect semantics are currently only supported in WSMan transport.643 if (connectionInfo is not WSManConnectionInfo)644 {645 throw new NotSupportedException();646 }647 648 _internalPool = new RemoteRunspacePoolInternal(instanceId, name, isDisconnected, connectCommands,649 connectionInfo, host, typeTable);650 651 IsRemote = true;652 }653 654 #endregion655 656 #region Public Properties657 658 /// <summary>659 /// Get unique id for this instance of runspace pool. It is primarily used660 /// for logging purposes.661 /// </summary>662 public Guid InstanceId663 {664 get665 {666 return _internalPool.InstanceId;667 }668 }669 670 /// <summary>671 /// Gets a boolean which describes if the runspace pool is disposed.672 /// </summary>673 public bool IsDisposed674 {675 get676 {677 return _internalPool.IsDisposed;678 }679 }680 681 /// <summary>682 /// Gets State of the current runspace pool.683 /// </summary>684 public RunspacePoolStateInfo RunspacePoolStateInfo685 {686 get687 {688 return _internalPool.RunspacePoolStateInfo;689 }690 }691 692 /// <summary>693 /// Gets the InitialSessionState object that this pool uses694 /// to create the runspaces.695 /// </summary>696 public InitialSessionState InitialSessionState697 {698 get699 {700 return _internalPool.InitialSessionState;701 }702 }703 704 /// <summary>705 /// Connection information for remote RunspacePools, null for local RunspacePools.706 /// </summary>707 public RunspaceConnectionInfo ConnectionInfo708 {709 get710 {711 return _internalPool.ConnectionInfo;712 }713 }714 715 /// <summary>716 /// Specifies how often unused runspaces are disposed.717 /// </summary>718 public TimeSpan CleanupInterval719 {720 get { return _internalPool.CleanupInterval; }721 722 set { _internalPool.CleanupInterval = value; }723 }724 725 /// <summary>726 /// Returns runspace pool availability.727 /// </summary>728 public RunspacePoolAvailability RunspacePoolAvailability729 {730 get { return _internalPool.RunspacePoolAvailability; }731 }732 733 #endregion734 735 #region events736 737 /// <summary>738 /// Event raised when RunspacePoolState changes.739 /// </summary>740 public event EventHandler<RunspacePoolStateChangedEventArgs> StateChanged741 {742 add743 {744 lock (_syncObject)745 {746 bool firstEntry = (InternalStateChanged == null);747 InternalStateChanged += value;748 if (firstEntry)749 {750 // call any event handlers on this object, replacing the751 // internalPool sender with 'this' since receivers752 // are expecting a RunspacePool.753 _internalPool.StateChanged += OnStateChanged;754 }755 }756 }757 758 remove759 {760 lock (_syncObject)761 {762 InternalStateChanged -= value;763 if (InternalStateChanged == null)764 {765 _internalPool.StateChanged -= OnStateChanged;766 }767 }768 }769 }770 771 /// <summary>772 /// Handle internal Pool state changed events.773 /// </summary>774 /// <param name="source"></param>775 /// <param name="args"></param>776 private void OnStateChanged(object source, RunspacePoolStateChangedEventArgs args)777 {778 if (ConnectionInfo is NewProcessConnectionInfo)779 {780 NewProcessConnectionInfo connectionInfo = ConnectionInfo as NewProcessConnectionInfo;781 if (connectionInfo.Process != null &&782 (args.RunspacePoolStateInfo.State == RunspacePoolState.Opened ||783 args.RunspacePoolStateInfo.State == RunspacePoolState.Broken))784 {785 connectionInfo.Process.RunspacePool = this;786 }787 }788 789 // call any event handlers on this, replacing the790 // internalPool sender with 'this' since receivers791 // are expecting a RunspacePool792 InternalStateChanged.SafeInvoke(this, args);793 }794 795 /// <summary>796 /// Event raised when one of the runspaces in the pool forwards an event to this instance.797 /// </summary>798 internal event EventHandler<PSEventArgs> ForwardEvent799 {800 add801 {802 lock (_syncObject)803 {804 bool firstEntry = InternalForwardEvent == null;805 806 InternalForwardEvent += value;807 808 if (firstEntry)809 {810 _internalPool.ForwardEvent += OnInternalPoolForwardEvent;811 }812 }813 }814 815 remove816 {817 lock (_syncObject)818 {819 InternalForwardEvent -= value;820 821 if (InternalForwardEvent == null)822 {823 _internalPool.ForwardEvent -= OnInternalPoolForwardEvent;824 }825 }826 }827 }828 829 /// <summary>830 /// Pass thru of the ForwardEvent event from the internal pool.831 /// </summary>832 private void OnInternalPoolForwardEvent(object sender, PSEventArgs e)833 {834 OnEventForwarded(e);835 }836 837 /// <summary>838 /// Raises the ForwardEvent event.839 /// </summary>840 private void OnEventForwarded(PSEventArgs e)841 {842 InternalForwardEvent?.Invoke(this, e);843 }844 845 /// <summary>846 /// Event raised when a new Runspace is created by the pool.847 /// </summary>848 internal event EventHandler<RunspaceCreatedEventArgs> RunspaceCreated849 {850 add851 {852 lock (_syncObject)853 {854 bool firstEntry = (InternalRunspaceCreated == null);855 InternalRunspaceCreated += value;856 if (firstEntry)857 {858 // call any event handlers on this object, replacing the859 // internalPool sender with 'this' since receivers860 // are expecting a RunspacePool.861 _internalPool.RunspaceCreated += OnRunspaceCreated;862 }863 }864 }865 866 remove867 {868 lock (_syncObject)869 {870 InternalRunspaceCreated -= value;871 if (InternalRunspaceCreated == null)872 {873 _internalPool.RunspaceCreated -= OnRunspaceCreated;874 }875 }876 }877 }878 879 /// <summary>880 /// Handle internal Pool RunspaceCreated events.881 /// </summary>882 /// <param name="source"></param>883 /// <param name="args"></param>884 private void OnRunspaceCreated(object source, RunspaceCreatedEventArgs args)885 {886 // call any event handlers on this, replacing the887 // internalPool sender with 'this' since receivers888 // are expecting a RunspacePool889 InternalRunspaceCreated.SafeInvoke(this, args);890 }891 892 #endregion events893 894 #region Public static methods.895 896 /// <summary>897 /// Queries the server for disconnected runspace pools and creates an array of runspace898 /// pool objects associated with each disconnected runspace pool on the server. Each899 /// runspace pool object in the returned array is in the Disconnected state and can be900 /// connected to the server by calling the Connect() method on the runspace pool.901 /// </summary>902 /// <param name="connectionInfo">Connection object for the target server.</param>903 /// <returns>Array of RunspacePool objects each in the Disconnected state.</returns>904 public static RunspacePool[] GetRunspacePools(RunspaceConnectionInfo connectionInfo)905 {906 return GetRunspacePools(connectionInfo, null, null);907 }908 909 /// <summary>910 /// Queries the server for disconnected runspace pools and creates an array of runspace911 /// pool objects associated with each disconnected runspace pool on the server. Each912 /// runspace pool object in the returned array is in the Disconnected state and can be913 /// connected to the server by calling the Connect() method on the runspace pool.914 /// </summary>915 /// <param name="connectionInfo">Connection object for the target server.</param>916 /// <param name="host">Client host object.</param>917 /// <returns>Array of RunspacePool objects each in the Disconnected state.</returns>918 public static RunspacePool[] GetRunspacePools(RunspaceConnectionInfo connectionInfo, PSHost host)919 {920 return GetRunspacePools(connectionInfo, host, null);921 }922 923 /// <summary>924 /// Queries the server for disconnected runspace pools and creates an array of runspace925 /// pool objects associated with each disconnected runspace pool on the server. Each926 /// runspace pool object in the returned array is in the Disconnected state and can be927 /// connected to the server by calling the Connect() method on the runspace pool.928 /// </summary>929 /// <param name="connectionInfo">Connection object for the target server.</param>930 /// <param name="host">Client host object.</param>931 /// <param name="typeTable">TypeTable object.</param>932 /// <returns>Array of RunspacePool objects each in the Disconnected state.</returns>933 public static RunspacePool[] GetRunspacePools(RunspaceConnectionInfo connectionInfo, PSHost host, TypeTable typeTable)934 {935 return RemoteRunspacePoolInternal.GetRemoteRunspacePools(connectionInfo, host, typeTable);936 }937 938 #endregion939 940 #region Public Disconnect-Connect API941 942 /// <summary>943 /// Disconnects the runspace pool synchronously. Runspace pool must be in Opened state.944 /// </summary>945 public void Disconnect()946 {947 _internalPool.Disconnect();948 }949 950 /// <summary>951 /// Disconnects the runspace pool asynchronously. Runspace pool must be in Opened state.952 /// </summary>953 /// <param name="callback">An AsyncCallback to call once the BeginClose completes.</param>954 /// <param name="state">A user supplied state to call the callback with.</param>955 public IAsyncResult BeginDisconnect(AsyncCallback callback, object state)956 {957 return _internalPool.BeginDisconnect(callback, state);958 }959 960 /// <summary>961 /// Waits for the pending asynchronous BeginDisconnect to complete.962 /// </summary>963 /// <param name="asyncResult">Asynchronous call result object.</param>964 public void EndDisconnect(IAsyncResult asyncResult)965 {966 _internalPool.EndDisconnect(asyncResult);967 }968 969 /// <summary>970 /// Connects the runspace pool synchronously. Runspace pool must be in disconnected state.971 /// </summary>972 public void Connect()973 {974 _internalPool.Connect();975 }976 977 /// <summary>978 /// Connects the runspace pool asynchronously. Runspace pool must be in disconnected state.979 /// </summary>980 /// <param name="callback"></param>981 /// <param name="state"></param>982 public IAsyncResult BeginConnect(AsyncCallback callback, object state)983 {984 return _internalPool.BeginConnect(callback, state);985 }986 987 /// <summary>988 /// Waits for the pending asynchronous BeginConnect to complete.989 /// </summary>990 /// <param name="asyncResult">Asynchronous call result object.</param>991 public void EndConnect(IAsyncResult asyncResult)992 {993 _internalPool.EndConnect(asyncResult);994 }995 996 /// <summary>997 /// Creates an array of PowerShell objects that are in the Disconnected state for998 /// all currently disconnected running commands associated with this runspace pool.999 /// </summary>1000 /// <returns></returns>1001 public Collection<PowerShell> CreateDisconnectedPowerShells()1002 {1003 return _internalPool.CreateDisconnectedPowerShells(this);1004 }1005 1006 /// <summary>1007 /// Returns RunspacePool capabilities.1008 /// </summary>1009 /// <returns>RunspacePoolCapability.</returns>1010 public RunspacePoolCapability GetCapabilities()1011 {1012 return _internalPool.GetCapabilities();1013 }1014 1015 #endregion1016 1017 #region Public API1018 1019 /// <summary>1020 /// Sets the maximum number of Runspaces that can be active concurrently1021 /// in the pool. All requests above that number remain queued until1022 /// runspaces become available.1023 /// </summary>1024 /// <param name="maxRunspaces">1025 /// The maximum number of runspaces in the pool.1026 /// </param>1027 /// <returns>1028 /// true if the change is successful; otherwise, false.1029 /// </returns>1030 /// <remarks>1031 /// You cannot set the number of runspaces to a number smaller than1032 /// the minimum runspaces.1033 /// </remarks>1034 public bool SetMaxRunspaces(int maxRunspaces)1035 {1036 return _internalPool.SetMaxRunspaces(maxRunspaces);1037 }1038 1039 /// <summary>1040 /// Retrieves the maximum number of runspaces the pool maintains.1041 /// </summary>1042 /// <returns>1043 /// The maximum number of runspaces in the pool1044 /// </returns>1045 public int GetMaxRunspaces()1046 {1047 return _internalPool.GetMaxRunspaces();1048 }1049 1050 /// <summary>1051 /// Sets the minimum number of Runspaces that the pool maintains1052 /// in anticipation of new requests.1053 /// </summary>1054 /// <param name="minRunspaces">1055 /// The minimum number of runspaces in the pool.1056 /// </param>1057 /// <returns>1058 /// true if the change is successful; otherwise, false.1059 /// </returns>1060 /// <remarks>1061 /// You cannot set the number of idle runspaces to a number smaller than1062 /// 1 or greater than maximum number of active runspaces.1063 /// </remarks>1064 public bool SetMinRunspaces(int minRunspaces)1065 {1066 return _internalPool.SetMinRunspaces(minRunspaces);1067 }1068 1069 /// <summary>1070 /// Retrieves the minimum number of runspaces the pool maintains.1071 /// </summary>1072 /// <returns>1073 /// The minimum number of runspaces in the pool1074 /// </returns>1075 public int GetMinRunspaces()1076 {1077 return _internalPool.GetMinRunspaces();1078 }1079 1080 /// <summary>1081 /// Retrieves the number of runspaces available at the time of calling1082 /// this method.1083 /// </summary>1084 /// <returns>1085 /// The number of available runspace in the pool.1086 /// </returns>1087 public int GetAvailableRunspaces()1088 {1089 return _internalPool.GetAvailableRunspaces();1090 }1091 1092 /// <summary>1093 /// Opens the runspacepool synchronously. RunspacePool must1094 /// be opened before it can be used.1095 /// </summary>1096 /// <exception cref="InvalidRunspacePoolStateException">1097 /// RunspacePoolState is not BeforeOpen1098 /// </exception>1099 public void Open()1100 {1101 _internalPool.Open();1102 }1103 1104 /// <summary>1105 /// Opens the RunspacePool asynchronously. RunspacePool must1106 /// be opened before it can be used.1107 /// To get the exceptions that might have occurred, call1108 /// EndOpen.1109 /// </summary>1110 /// <param name="callback">1111 /// A AsyncCallback to call once the BeginOpen completes.1112 /// </param>1113 /// <param name="state">1114 /// A user supplied state to call the <paramref name="callback"/>1115 /// with.1116 /// </param>1117 /// <returns>1118 /// An AsyncResult object to monitor the state of the async1119 /// operation.1120 /// </returns>1121 public IAsyncResult BeginOpen(AsyncCallback callback, object state)1122 {1123 return _internalPool.BeginOpen(callback, state);1124 }1125 1126 /// <summary>1127 /// Waits for the pending asynchronous BeginOpen to complete.1128 /// </summary>1129 /// <exception cref="ArgumentNullException">1130 /// asyncResult is a null reference.1131 /// </exception>1132 /// <exception cref="ArgumentException">1133 /// asyncResult object was not created by calling BeginOpen1134 /// on this runspacepool instance.1135 /// </exception>1136 /// <exception cref="InvalidRunspacePoolStateException">1137 /// RunspacePoolState is not BeforeOpen.1138 /// </exception>1139 /// <remarks>1140 /// TODO: Behavior if EndOpen is called multiple times.1141 /// </remarks>1142 public void EndOpen(IAsyncResult asyncResult)1143 {1144 _internalPool.EndOpen(asyncResult);1145 }1146 1147 /// <summary>1148 /// Closes the RunspacePool and cleans all the internal1149 /// resources. This will close all the runspaces in the1150 /// runspacepool and release all the async operations1151 /// waiting for a runspace. If the pool is already closed1152 /// or broken or closing this will just return.1153 /// </summary>1154 /// <exception cref="InvalidRunspacePoolStateException">1155 /// Cannot close the RunspacePool because RunspacePool is1156 /// in Closing state.1157 /// </exception>1158 public void Close()1159 {1160 _internalPool.Close();1161 }1162 1163 /// <summary>1164 /// Closes the RunspacePool asynchronously and cleans all the internal1165 /// resources. This will close all the runspaces in the1166 /// runspacepool and release all the async operations1167 /// waiting for a runspace. If the pool is already closed1168 /// or broken or closing this will just return.1169 /// </summary>1170 /// <param name="callback">1171 /// A AsyncCallback to call once the BeginClose completes.1172 /// </param>1173 /// <param name="state">1174 /// A user supplied state to call the <paramref name="callback"/>1175 /// with.1176 /// </param>1177 /// <returns>1178 /// An AsyncResult object to monitor the state of the async1179 /// operation.1180 /// </returns>1181 public IAsyncResult BeginClose(AsyncCallback callback, object state)1182 {1183 return _internalPool.BeginClose(callback, state);1184 }1185 1186 /// <summary>1187 /// Waits for the pending asynchronous BeginClose to complete.1188 /// </summary>1189 /// <exception cref="ArgumentNullException">1190 /// asyncResult is a null reference.1191 /// </exception>1192 /// <exception cref="ArgumentException">1193 /// asyncResult object was not created by calling BeginClose1194 /// on this runspacepool instance.1195 /// </exception>1196 public void EndClose(IAsyncResult asyncResult)1197 {1198 _internalPool.EndClose(asyncResult);1199 }1200 