2016-03-30 14:20:52 -07:00
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
2016-07-29 13:02:49 -07:00
2016-03-30 14:20:52 -07:00
using System.Diagnostics.CodeAnalysis ;
using System.Runtime.Serialization ;
using System.Threading ;
using System.Management.Automation.Host ;
using System.Management.Automation.Internal ;
using System.Collections.Generic ;
using System.Collections.ObjectModel ;
using Dbg = System . Management . Automation . Diagnostics ;
#if CORECLR
// Use stub for SerializableAttribute, NonSerializedAttribute and ISerializable related types
using Microsoft.PowerShell.CoreClr.Stubs ;
#endif
namespace System.Management.Automation.Runspaces
{
#region Exceptions
/// <summary>
/// Exception thrown when state of the runspace is different from
/// expected state of runspace.
/// </summary>
[Serializable]
public class InvalidRunspaceStateException : SystemException
{
/// <summary>
/// Initializes a new instance of InvalidRunspaceStateException
/// </summary>
2016-07-29 13:02:49 -07:00
public InvalidRunspaceStateException ()
: base
2016-03-30 14:20:52 -07:00
(
StringUtil . Format ( RunspaceStrings . InvalidRunspaceStateGeneral )
)
{
}
/// <summary>
/// Initializes a new instance of InvalidRunspaceStateException with a specified error message.
/// </summary>
/// <param name="message">
/// The message that describes the error.
/// </param>
2016-07-29 13:02:49 -07:00
public InvalidRunspaceStateException ( string message )
: base ( message )
2016-03-30 14:20:52 -07:00
{
}
/// <summary>
/// Initializes a new instance of the InvalidRunspaceStateException class
/// with a specified error message and a reference to the inner exception
/// that is the cause of this exception.
/// </summary>
/// <param name="message">
/// The message that describes the error.
/// </param>
/// <param name="innerException">
/// The exception that is the cause of the current exception.
/// </param>
2016-07-29 13:02:49 -07:00
public InvalidRunspaceStateException ( string message , Exception innerException )
: base ( message , innerException )
2016-03-30 14:20:52 -07:00
{
}
2016-07-29 13:02:49 -07:00
2016-03-30 14:20:52 -07:00
/// <summary>
/// Initializes a new instance of the InvalidRunspaceStateException
/// with a specified error message and current and expected state.
/// </summary>
/// <param name="message">The message that describes the error. </param>
/// <param name="currentState">Current state of runspace</param>
/// <param name="expectedState">Expected states of runspace</param>
2016-07-29 13:02:49 -07:00
internal InvalidRunspaceStateException
2016-03-30 14:20:52 -07:00
(
2016-07-29 13:02:49 -07:00
string message ,
RunspaceState currentState ,
2016-03-30 14:20:52 -07:00
RunspaceState expectedState
2016-07-29 13:02:49 -07:00
)
: base ( message )
2016-03-30 14:20:52 -07:00
{
_expectedState = expectedState ;
_currentState = currentState ;
}
#region ISerializable Members
// 2005/04/20-JonN No need to implement GetObjectData
// if all fields are static or [NonSerialized]
/// <summary>
/// Initializes a new instance of the <see cref="InvalidRunspaceStateException"/>
/// class with serialized data.
/// </summary>
/// <param name="info">
/// The <see cref="SerializationInfo"/> that holds the serialized object
/// data about the exception being thrown.
/// </param>
/// <param name="context">
/// The <see cref="StreamingContext"/> that contains contextual information
/// about the source or destination.
/// </param>
2016-07-29 13:02:49 -07:00
protected InvalidRunspaceStateException ( SerializationInfo info , StreamingContext context )
2016-03-30 14:20:52 -07:00
: base ( info , context )
{
}
#endregion
/// <summary>
/// Access CurrentState of the runspace.
/// </summary>
/// <remarks>This is the state of the runspace when exception was thrown.
/// </remarks>
public RunspaceState CurrentState
{
get
{
return _currentState ;
}
internal set
{
_currentState = value ;
}
}
/// <summary>
/// Expected state of runspace by the operation which has thrown this exception.
/// </summary>
public RunspaceState ExpectedState
{
get
{
return _expectedState ;
}
internal set
{
_expectedState = value ;
}
}
/// <summary>
/// State of the runspace when exception was thrown.
/// </summary>
[NonSerialized]
private RunspaceState _currentState = 0 ;
/// <summary>
/// States of the runspace expected in method which throws this exception.
/// </summary>
[NonSerialized]
private RunspaceState _expectedState = 0 ;
}
2016-07-29 13:02:49 -07:00
2016-03-30 14:20:52 -07:00
#endregion Exceptions
#region Runspace state
/// <summary>
/// Defines various states of runspace.
/// </summary>
public enum RunspaceState
{
/// <summary>
/// Beginning state upon creation
/// </summary>
BeforeOpen = 0 ,
/// <summary>
/// A runspace is being established.
/// </summary>
Opening = 1 ,
/// <summary>
/// The runspace is established and valid.
/// </summary>
Opened = 2 ,
/// <summary>
/// The runspace is closed or has not been established.
/// </summary>
Closed = 3 ,
/// <summary>
/// The runspace is being closed
/// </summary>
Closing = 4 ,
/// <summary>
/// The runspace has been disconnected abnormally.
/// </summary>
Broken = 5 ,
/// <summary>
/// The runspace is being disconnected.
/// </summary>
Disconnecting = 6 ,
/// <summary>
/// The runspace is disconnected.
/// </summary>
Disconnected = 7 ,
/// <summary>
/// The runspace is Connecting.
/// </summary>
Connecting = 8
}
/// <summary>
/// These options control whether a new thread is created when a command is executed within a runspace
/// </summary>
public enum PSThreadOptions
{
/// <summary>
/// Use the default options: UseNewThread for local Runspace, ReuseThread for local RunspacePool, server settings for remote Runspace and RunspacePool
/// </summary>
Default = 0 ,
/// <summary>
/// Creates a new thread for each invocation
/// </summary>
UseNewThread = 1 ,
/// <summary>
/// Creates a new thread for the first invocation and then re-uses
/// that thread in subsequent invocations.
/// </summary>
ReuseThread = 2 ,
/// <summary>
/// Doesn’ t create a new thread; the execution occurs on the
/// thread that calls Invoke.
/// </summary>
/// <remarks>
/// This option is not valid for asynchronous calls
/// </remarks>
UseCurrentThread = 3
};
/// <summary>
/// Defines type which has information about RunspaceState and
/// Exception associated with RunspaceState
/// </summary>
public sealed class RunspaceStateInfo
{
#region constructors
/// <summary>
/// Constructor for state changes not resulting from an error.
/// </summary>
/// <param name="state">The state of the runspace.</param>
2016-07-29 13:02:49 -07:00
internal RunspaceStateInfo ( RunspaceState state )
: this ( state , null )
2016-03-30 14:20:52 -07:00
{
}
/// <summary>
/// Constructor for state changes with an optional error
/// </summary>
/// <param name="state">The state of runspace.</param>
/// <param name="reason">A non-null exception if the state change was
/// caused by an error, otherwise; null.
/// </param>
2016-07-29 13:02:49 -07:00
internal RunspaceStateInfo ( RunspaceState state , Exception reason )
2016-03-30 14:20:52 -07:00
: base ()
{
_state = state ;
_reason = reason ;
}
/// <summary>
/// Copy constructor to support cloning.
/// </summary>
/// <param name="runspaceStateInfo">The source
/// RunspaceStateInfo
/// </param>
2016-07-29 13:02:49 -07:00
internal RunspaceStateInfo ( RunspaceStateInfo runspaceStateInfo )
2016-03-30 14:20:52 -07:00
{
_state = runspaceStateInfo . State ;
_reason = runspaceStateInfo . Reason ;
}
#endregion constructors
#region public_properties
/// <summary>
/// The state of the runspace.
/// </summary>
public RunspaceState State
{
get
{
return _state ;
}
}
/// <summary>
/// The reason for the state change, if caused by an error.
/// </summary>
/// <remarks>
/// The value of this property is non-null if the state
/// changed due to an error. Otherwise, the value of this
/// property is null.
/// </remarks>
public Exception Reason
{
get
{
return _reason ;
}
}
#endregion public_properties
/// <summary>
/// override for ToString()
/// </summary>
/// <returns></returns>
public override string ToString ()
{
return _state . ToString ();
}
/// <summary>
/// Clones current object
/// </summary>
/// <returns>Cloned object</returns>
internal RunspaceStateInfo Clone ()
{
return new RunspaceStateInfo ( this );
}
#region private_fields
/// <summary>
/// State of runspace
/// </summary>
private RunspaceState _state ;
/// <summary>
/// The reason for the state change, if caused by an error.
/// </summary>
private Exception _reason ;
#endregion private_fields
}
/// <summary>
/// Defines Event arguments passed to RunspaceStateEvent handler
/// <see cref="Runspace.StateChanged"/> event.
/// </summary>
public sealed class RunspaceStateEventArgs : EventArgs
{
#region constructors
/// <summary>
/// Constructs RunspaceStateEventArgs using RunspaceStateInfo
/// </summary>
/// <param name="runspaceStateInfo">The information about
/// current state of the runspace.</param>
/// <exception cref="ArgumentNullException">runspaceStateInfo is null
/// </exception>
2016-07-29 13:02:49 -07:00
internal RunspaceStateEventArgs ( RunspaceStateInfo runspaceStateInfo )
2016-03-30 14:20:52 -07:00
{
if ( runspaceStateInfo == null )
{
2016-07-29 13:02:49 -07:00
throw PSTraceSource . NewArgumentNullException ( "runspaceStateInfo" );
2016-03-30 14:20:52 -07:00
}
_runspaceStateInfo = runspaceStateInfo ;
}
#endregion constructors
#region public_properties
/// <summary>
/// Information about state of the runspace
/// </summary>
/// <remarks>
/// This value indicates the state of the runspace after the
/// change.
/// </remarks>
public RunspaceStateInfo RunspaceStateInfo
{
get
{
return _runspaceStateInfo ;
}
}
#endregion public_properties
/// <summary>
/// RunspaceStateInfo when event raised.
/// </summary>
private RunspaceStateInfo _runspaceStateInfo ;
}
/// <summary>
/// Enum to indicate whether a Runspace is busy or available
/// </summary>
public enum RunspaceAvailability
{
/// <summary>
/// The Runspace is not been in the Opened state
/// </summary>
None = 0 ,
/// <summary>
/// The Runspace is available to execute commands
/// </summary>
Available ,
/// <summary>
/// The Runspace is available to execute nested commands
/// </summary>
AvailableForNestedCommand ,
/// <summary>
/// The Runspace is busy executing a command
/// </summary>
Busy ,
/// <summary>
/// Applies only to remote runspace case. The remote runspace
/// is currently in a Debugger Stop mode and requires a debugger
/// SetDebuggerAction() call to continue.
/// </summary>
RemoteDebug
}
/// <summary>
/// Defines the event arguments passed to the AvailabilityChanged <see cref="Runspace.AvailabilityChanged"/> event.
/// </summary>
public sealed class RunspaceAvailabilityEventArgs : EventArgs
{
internal RunspaceAvailabilityEventArgs ( RunspaceAvailability runspaceAvailability )
{
_runspaceAvailability = runspaceAvailability ;
}
/// <summary>
/// Whether the Runspace is available to execute commands
/// </summary>
public RunspaceAvailability RunspaceAvailability
{
get
{
return _runspaceAvailability ;
}
}
private RunspaceAvailability _runspaceAvailability ;
}
#endregion Runspace state
#region Runspace capabilities
/// <summary>
/// Defines runspace capabilities.
/// </summary>
public enum RunspaceCapability
{
/// <summary>
/// No additional capabilites beyond a default runspace.
/// </summary>
Default = 0x0 ,
/// <summary>
/// Runspace and remoting layer supports disconnect/connect feature.
/// </summary>
SupportsDisconnect = 0x1 ,
/// <summary>
/// Runspace is based on a named pipe transport.
/// </summary>
2016-04-12 13:06:17 -07:00
NamedPipeTransport = 0x2 ,
/// <summary>
/// Runspace is based on a VM socket transport.
/// </summary>
VMSocketTransport = 0x4
2016-03-30 14:20:52 -07:00
}
#endregion
/// <summary>
/// Public interface to Msh Runtime. Provides APIs for creating pipelines,
/// access session state etc.
/// </summary>
public abstract class Runspace : IDisposable
{
#region Private Data
2016-07-29 13:02:49 -07:00
private static int s_globalId ;
2016-03-30 14:20:52 -07:00
private Stack < PowerShell > _runningPowerShells ;
private PowerShell _baseRunningPowerShell ;
private object _syncObject ;
#endregion
#region constructor
/// <summary>
/// Explicit default constructor
/// </summary>
internal Runspace ()
{
// Create the default Runspace Id and friendly name.
2016-07-29 13:02:49 -07:00
Id = System . Threading . Interlocked . Increment ( ref s_globalId );
2016-03-30 14:20:52 -07:00
Name = "Runspace" + Id . ToString ( System . Globalization . NumberFormatInfo . InvariantInfo );
_runningPowerShells = new Stack < PowerShell >();
_syncObject = new object ();
// Keep track of this runspace until it is disposed.
lock ( s_syncObject )
{
s_runspaceDictionary . Add ( Id , new WeakReference < Runspace >( this ));
}
}
/// <summary>
/// Static Constructor
/// </summary>
static Runspace ()
{
s_syncObject = new object ();
s_runspaceDictionary = new SortedDictionary < int , WeakReference < Runspace >>();
2016-07-29 13:02:49 -07:00
s_globalId = 0 ;
2016-03-30 14:20:52 -07:00
}
#endregion constructor
#region properties
/// <summary>
/// Used to store Runspace reference on per thread basis. Used by
/// various PowerShell engine features to get access to TypeTable
/// etc.
/// </summary>
[ThreadStatic]
2016-07-29 13:02:49 -07:00
private static Runspace t_threadSpecificDefaultRunspace = null ;
2016-03-30 14:20:52 -07:00
/// <summary>
/// Gets and sets the default Runspace used to evaluate scripts
/// </summary>
/// <remarks>The Runspace used to set this property should not be shared between different threads.</remarks>
public static Runspace DefaultRunspace
{
get
{
2016-07-29 13:02:49 -07:00
return t_threadSpecificDefaultRunspace ;
2016-03-30 14:20:52 -07:00
}
set
{
2016-07-29 13:02:49 -07:00
if ( value == null || ! value . RunspaceIsRemote )
2016-03-30 14:20:52 -07:00
{
2016-07-29 13:02:49 -07:00
t_threadSpecificDefaultRunspace = value ;
2016-03-30 14:20:52 -07:00
}
else
{
throw new InvalidOperationException ( RunspaceStrings . RunspaceNotLocal );
}
}
}
/// <summary>
/// Returns true if Runspace.DefaultRunspace can be used to
/// create an instance of the PowerShell class with
/// 'UseCurrentRunspace = true'.
/// </summary>
public static bool CanUseDefaultRunspace
{
// can use default runspace in a thread safe manner only if
// 1. we have a default runspace
// 2. we recognize the type of current runspace and current pipeline
// 3. the pipeline executes on the same thread as this method
// we don't return "true" for
// 1. we have a default runspace
// 2. no currently executing pipeline
// to avoid a race condition where a pipeline is started
// after this property getter did all the checks
get
{
RunspaceBase runspace = Runspace . DefaultRunspace as RunspaceBase ;
if ( runspace != null )
{
Pipeline currentPipeline = runspace . GetCurrentlyRunningPipeline ();
LocalPipeline localPipeline = currentPipeline as LocalPipeline ;
if (( localPipeline != null ) && ( localPipeline . NestedPipelineExecutionThread != null ))
{
return
( localPipeline . NestedPipelineExecutionThread . ManagedThreadId
== Threading . Thread . CurrentThread . ManagedThreadId );
}
}
return false ;
}
}
#if ! CORECLR // No ApartmentState In CoreCLR
internal const ApartmentState DefaultApartmentState = ApartmentState . Unknown ;
/// <summary>
/// ApartmentState of the thread used to execute commands within this Runspace
/// </summary>
/// <remarks>
/// Any updates to the value of this property must be done before the Runspace is opened
/// </remarks>
/// <exception cref="InvalidRunspaceStateException">
/// An attempt to change this property was made after opening the Runspace
/// </exception>
public ApartmentState ApartmentState
{
get
{
return this . apartmentState ;
}
set
{
if ( this . RunspaceStateInfo . State != RunspaceState . BeforeOpen )
{
throw new InvalidRunspaceStateException ( StringUtil . Format ( RunspaceStrings . ChangePropertyAfterOpen ));
}
this . apartmentState = value ;
}
}
private ApartmentState apartmentState = Runspace . DefaultApartmentState ;
#endif
/// <summary>
/// This property determines whether a new thread is create for each invocation
/// </summary>
/// <remarks>
/// Any updates to the value of this property must be done before the Runspace is opened
/// </remarks>
/// <exception cref="InvalidRunspaceStateException">
/// An attempt to change this property was made after opening the Runspace
/// </exception>
/// <exception cref="InvalidOperationException">
/// The thread options cannot be changed to the requested value
/// </exception>
public abstract PSThreadOptions ThreadOptions
{
get ;
set ;
}
/// <summary>
/// Return version of this runspace
/// </summary>
public abstract Version Version
{
get ;
}
/// <summary>
/// Return whether the Runspace is Remote
/// We can determine this by whether the runspace is an implementation of LocalRunspace
/// or infer it from whether the ConnectionInfo property is null
/// If it happens to be an instance of a LocalRunspace, but has a non-null ConnectionInfo
/// we declare it to be remote
/// </summary>
public bool RunspaceIsRemote
{
2016-07-29 13:02:49 -07:00
get
2016-03-30 14:20:52 -07:00
{
2016-07-29 13:02:49 -07:00
return !( this is LocalRunspace || ConnectionInfo == null );
2016-03-30 14:20:52 -07:00
}
}
/// <summary>
/// Retrieve information about current state of the runspace
/// </summary>
public abstract RunspaceStateInfo RunspaceStateInfo
{
get ;
}
/// <summary>
/// Gets the current availability of the Runspace
/// </summary>
public abstract RunspaceAvailability RunspaceAvailability
{
get ;
protected set ;
}
private Guid _instanceId = Guid . NewGuid ();
/// <summary>
/// RunspaceConfiguration information for this runspace.
/// </summary>
2016-04-28 13:41:25 -07:00
#if CORECLR
internal
#else
public
#endif
abstract RunspaceConfiguration RunspaceConfiguration
2016-03-30 14:20:52 -07:00
{
get ;
}
/// <summary>
/// InitialSessionState information for this runspace.
/// </summary>
public abstract InitialSessionState InitialSessionState
{
get ;
}
/// <summary>
/// Get unqiue id for this instance of runspace. It is primarily used
/// for logging purposes
/// </summary>
public Guid InstanceId
{
get
{
return _instanceId ;
}
// This id is also used to identify proxy and remote runspace objects.
// We need to set this when reconstructing a remote runspace to connect
// to an existing remote runspace.
internal set
{
_instanceId = value ;
}
}
/// <summary>
/// Gets execution context.
/// </summary>
/// <exception cref="InvalidRunspaceStateException">Runspace is not opened.
/// </exception>
internal System . Management . Automation . ExecutionContext ExecutionContext
{
get
{
return GetExecutionContext ;
}
}
2016-07-29 13:02:49 -07:00
private bool _skipUserProfile = false ;
2016-03-30 14:20:52 -07:00
/// <summary>
/// Skip user profile on engine initialization
/// </summary>
internal bool SkipUserProfile
{
get
{
return _skipUserProfile ;
}
set
{
_skipUserProfile = value ;
}
}
/// <summary>
/// Connection information for remote Runspaces, null for local Runspaces
/// </summary>
2016-07-29 13:02:49 -07:00
public abstract RunspaceConnectionInfo ConnectionInfo { get ; }
2016-03-30 14:20:52 -07:00
/// <summary>
/// ConnectionInfo originally supplied by the user
/// </summary>
public abstract RunspaceConnectionInfo OriginalConnectionInfo { get ; }
/// <summary>
/// Manager for JobSourceAdapters registered in this runspace.
/// </summary>
public abstract JobManager JobManager { get ; }
/// <summary>
/// DisconnectedOn property applies to remote runspaces that have
/// been disconnected.
/// </summary>
public DateTime ? DisconnectedOn
{
get ;
internal set ;
}
/// <summary>
/// ExpiresOn property applies to remote runspaces that have been
/// disconnected.
/// </summary>
public DateTime ? ExpiresOn
{
get ;
internal set ;
}
/// <summary>
/// Gets and sets a friendly name for the Runspace.
/// </summary>
public string Name
{
get ;
set ;
}
/// <summary>
/// Gets the Runspace Id.
/// </summary>
public int Id
{
get ;
private set ;
}
/// <summary>
/// Returns protocol version that the remote server uses for PS remoting
/// </summary>
internal Version GetRemoteProtocolVersion ()
{
Version remoteProtocolVersionDeclaredByServer ;
bool isServerDeclarationValid = PSPrimitiveDictionary . TryPathGet (
this . GetApplicationPrivateData (),
out remoteProtocolVersionDeclaredByServer ,
PSVersionInfo . PSVersionTableName ,
PSVersionInfo . PSRemotingProtocolVersionName );
if ( isServerDeclarationValid )
{
return remoteProtocolVersionDeclaredByServer ;
}
else
{
return RemotingConstants . ProtocolVersion ;
}
}
/// <summary>
/// Engine activity id (for ETW tracing)
/// </summary>
internal Guid EngineActivityId
{
get { return _engineActivityId ; }
set { _engineActivityId = value ; }
}
private Guid _engineActivityId = Guid . Empty ;
/// <summary>
/// Returns a read only runspace dictionary.
/// </summary>
internal static ReadOnlyDictionary < int , WeakReference < Runspace >> RunspaceDictionary
{
get
{
lock ( s_syncObject )
{
2016-07-29 13:02:49 -07:00
return new ReadOnlyDictionary < int , WeakReference < Runspace >>( new Dictionary < int , WeakReference < Runspace >>( s_runspaceDictionary ));
2016-03-30 14:20:52 -07:00
}
}
}
private static SortedDictionary < int , WeakReference < Runspace >> s_runspaceDictionary ;
private static object s_syncObject ;
/// <summary>
/// Returns a read only list of runspaces.
/// </summary>
internal static IReadOnlyList < Runspace > RunspaceList
{
get
{
List < Runspace > runspaceList = new List < Runspace >();
lock ( s_syncObject )
{
foreach ( var item in s_runspaceDictionary . Values )
{
Runspace runspace ;
if ( item . TryGetTarget ( out runspace ))
{
runspaceList . Add ( runspace );
}
}
}
return new ReadOnlyCollection < Runspace >( runspaceList );
}
}
#endregion properties
#region events
/// <summary>
/// Event raised when RunspaceState changes.
/// </summary>
public abstract event EventHandler < RunspaceStateEventArgs > StateChanged ;
/// <summary>
/// Event raised when the availability of the Runspace changes.
/// </summary>
public abstract event EventHandler < RunspaceAvailabilityEventArgs > AvailabilityChanged ;
/// <summary>
/// Returns true if there are any subscribers to the AvailabilityChanged event
/// </summary>
internal abstract bool HasAvailabilityChangedSubscribers
{
get ;
}
/// <summary>
/// Raises the AvailabilityChanged event
/// </summary>
protected abstract void OnAvailabilityChanged ( RunspaceAvailabilityEventArgs e );
/// <summary>
/// Used to raise the AvailabilityChanged event when the state of the currently executing pipeline changes
/// </summary>
/// <remarks>
/// The possible pipeline states are
/// NotStarted
/// Running
/// Disconnected
/// Stopping
/// Stopped
/// Completed
/// Failed
/// </remarks>
internal void UpdateRunspaceAvailability ( PipelineState pipelineState , bool raiseEvent , Guid ? cmdInstanceId = null )
{
RunspaceAvailability oldAvailability = this . RunspaceAvailability ;
switch ( oldAvailability )
{
// Because of disconnect/connect support runspace availability can now transition
// in and out of "None" state.
case RunspaceAvailability . None :
switch ( pipelineState )
{
case PipelineState . Running :
this . RunspaceAvailability = RunspaceAvailability . Busy ;
break ;
2016-07-29 13:02:49 -07:00
// Otherwise no change.
2016-03-30 14:20:52 -07:00
}
break ;
2016-07-29 13:02:49 -07:00
2016-03-30 14:20:52 -07:00
case RunspaceAvailability . Available :
switch ( pipelineState )
{
case PipelineState . Running :
this . RunspaceAvailability = RunspaceAvailability . Busy ;
break ;
case PipelineState . Disconnected :
this . RunspaceAvailability = Runspaces . RunspaceAvailability . None ;
break ;
}
break ;
case RunspaceAvailability . AvailableForNestedCommand :
switch ( pipelineState )
{
case PipelineState . Running :
this . RunspaceAvailability = RunspaceAvailability . Busy ;
break ;
case PipelineState . Completed : // a nested pipeline caused the host to exit nested prompt
2016-07-29 13:02:49 -07:00
this . RunspaceAvailability = ( this . InNestedPrompt || ( _runningPowerShells . Count > 1 )) ?
2016-03-30 14:20:52 -07:00
RunspaceAvailability . AvailableForNestedCommand : RunspaceAvailability . Available ;
break ;
default :
break ; // no change in the availability
}
break ;
case RunspaceAvailability . Busy :
case RunspaceAvailability . RemoteDebug :
switch ( pipelineState )
{
case PipelineState . Disconnected :
if ( oldAvailability == Runspaces . RunspaceAvailability . RemoteDebug )
{
this . RunspaceAvailability = RunspaceAvailability . RemoteDebug ;
}
else
{
this . RunspaceAvailability = RunspaceAvailability . None ;
}
break ;
case PipelineState . Stopping :
break ; // no change in the availability
case PipelineState . Completed :
case PipelineState . Stopped :
case PipelineState . Failed :
if ( this . InNestedPrompt || !( this is RemoteRunspace ) && this . Debugger . InBreakpoint )
{
this . RunspaceAvailability = RunspaceAvailability . AvailableForNestedCommand ;
}
else
{
RemoteRunspace remoteRunspace = this as RemoteRunspace ;
RemoteDebugger remoteDebugger = ( remoteRunspace != null ) ? remoteRunspace . Debugger as RemoteDebugger : null ;
Internal . ConnectCommandInfo remoteCommand = ( remoteRunspace != null ) ? remoteRunspace . RemoteCommand : null ;
if ((( pipelineState == PipelineState . Completed ) || ( pipelineState == PipelineState . Failed ) ||
(( pipelineState == PipelineState . Stopped ) && ( this . RunspaceStateInfo . State == RunspaceState . Opened )))
&& ( remoteCommand != null ) && ( cmdInstanceId != null ) && ( remoteCommand . CommandId == cmdInstanceId ))
{
// Completed, Failed, and Stopped with Runspace.Opened states are command finish states and we know
// that the command is finished on the server.
// Setting ConnectCommands to null indicates that the runspace is free to run other
// commands.
remoteRunspace . RunspacePool . RemoteRunspacePoolInternal . ConnectCommands = null ;
remoteCommand = null ;
if (( remoteDebugger != null ) && ( pipelineState == PipelineState . Stopped ))
{
// Notify remote debugger of a stop in case the stop occurred while command was in debug stop.
remoteDebugger . OnCommandStopped ();
}
}
Pipeline currentPipeline = this . GetCurrentlyRunningPipeline ();
RemotePipeline remotePipeline = currentPipeline as RemotePipeline ;
Guid ? pipeLineCmdInstance = ( remotePipeline != null && remotePipeline . PowerShell != null ) ? remotePipeline . PowerShell . InstanceId : ( Guid ?) null ;
if ( currentPipeline == null )
{
// A runspace is available:
// - if there is no currently running pipeline
// and for remote runspaces:
// - if there is no remote command associated with it.
// - if the remote runspace pool is marked as available for connection.
if ( remoteCommand == null )
{
if ( remoteRunspace != null )
{
if (( remoteDebugger != null ) && ( pipelineState == PipelineState . Stopped ))
{
// Notify remote debugger of a stop in case the stop occurred while command was in debug stop.
remoteDebugger . OnCommandStopped ();
}
this . RunspaceAvailability =
remoteRunspace . RunspacePool . RemoteRunspacePoolInternal . AvailableForConnection ?
RunspaceAvailability . Available : Runspaces . RunspaceAvailability . Busy ;
}
else
{
this . RunspaceAvailability = RunspaceAvailability . Available ;
}
}
}
else if (( cmdInstanceId != null ) && ( pipeLineCmdInstance != null ) && ( cmdInstanceId == pipeLineCmdInstance ))
{
if (( remoteDebugger != null ) && ( pipelineState == PipelineState . Stopped ))
{
// Notify remote debugger of a stop in case the stop occurred while command was in debug stop.
remoteDebugger . OnCommandStopped ();
}
this . RunspaceAvailability = RunspaceAvailability . Available ;
}
else // a nested pipeline completed, but the parent pipeline is still running
{
if ( oldAvailability == Runspaces . RunspaceAvailability . RemoteDebug )
{
this . RunspaceAvailability = Runspaces . RunspaceAvailability . RemoteDebug ;
}
2016-07-29 13:02:49 -07:00
else if (( currentPipeline . PipelineStateInfo . State == PipelineState . Running ) || ( _runningPowerShells . Count > 1 ))
2016-03-30 14:20:52 -07:00
{
// Either the current pipeline is running or there are other nested commands to run in the Runspace.
this . RunspaceAvailability = RunspaceAvailability . Busy ;
}
else
{
this . RunspaceAvailability = RunspaceAvailability . Available ;
}
}
}
break ;
case PipelineState . Running : // this can happen if a nested pipeline is created without entering a nested prompt
2016-07-29 13:02:49 -07:00
break ; // no change in the availability
2016-03-30 14:20:52 -07:00
default :
2016-07-29 13:02:49 -07:00
break ; // no change in the availability
2016-03-30 14:20:52 -07:00
}
break ;
default :
Diagnostics . Assert ( false , "Invalid RunspaceAvailability" );
break ;
}
if ( raiseEvent && this . RunspaceAvailability != oldAvailability )
{
OnAvailabilityChanged ( new RunspaceAvailabilityEventArgs ( this . RunspaceAvailability ));
}
}
/// <summary>
/// Used to update the runspace availability when the state of the currently executing PowerShell instance changes
/// </summary>
/// <remarks>
/// The possible invocation states are
/// NotStarted
/// Running
/// Stopping
/// Stopped
/// Completed
/// Failed
/// </remarks>
internal void UpdateRunspaceAvailability ( PSInvocationState invocationState , bool raiseEvent , Guid cmdInstanceId )
{
switch ( invocationState )
{
case PSInvocationState . NotStarted :
UpdateRunspaceAvailability ( PipelineState . NotStarted , raiseEvent , cmdInstanceId );
break ;
case PSInvocationState . Running :
UpdateRunspaceAvailability ( PipelineState . Running , raiseEvent , cmdInstanceId );
break ;
case PSInvocationState . Completed :
UpdateRunspaceAvailability ( PipelineState . Completed , raiseEvent , cmdInstanceId );
break ;
case PSInvocationState . Failed :
UpdateRunspaceAvailability ( PipelineState . Failed , raiseEvent , cmdInstanceId );
break ;
case PSInvocationState . Stopping :
UpdateRunspaceAvailability ( PipelineState . Stopping , raiseEvent , cmdInstanceId );
break ;
case PSInvocationState . Stopped :
UpdateRunspaceAvailability ( PipelineState . Stopped , raiseEvent , cmdInstanceId );
break ;
case PSInvocationState . Disconnected :
UpdateRunspaceAvailability ( PipelineState . Disconnected , raiseEvent , cmdInstanceId );
break ;
default :
Diagnostics . Assert ( false , "Invalid PSInvocationState" );
break ;
}
}
/// <summary>
/// Used to update the runspace availability event when the state of the runspace changes
/// </summary>
/// <remarks>
/// The possible runspace states are:
/// BeforeOpen
/// Opening
/// Opened
/// Closed
/// Closing
/// Broken
/// </remarks>
protected void UpdateRunspaceAvailability ( RunspaceState runspaceState , bool raiseEvent )
{
RunspaceAvailability oldAvailability = this . RunspaceAvailability ;
RemoteRunspace remoteRunspace = this as RemoteRunspace ;
Internal . ConnectCommandInfo remoteCommand = null ;
bool remoteDebug = false ;
if ( remoteRunspace != null )
{
remoteCommand = remoteRunspace . RemoteCommand ;
RemoteDebugger remoteDebugger = remoteRunspace . Debugger as RemoteDebugger ;
remoteDebug = ( remoteDebugger != null ) && remoteDebugger . IsRemoteDebug ;
}
switch ( oldAvailability )
{
case RunspaceAvailability . None :
switch ( runspaceState )
{
case RunspaceState . Opened :
if ( remoteDebug )
{
this . RunspaceAvailability = Runspaces . RunspaceAvailability . RemoteDebug ;
}
else
{
this . RunspaceAvailability = ( remoteCommand == null && GetCurrentlyRunningPipeline () == null ) ?
RunspaceAvailability . Available : RunspaceAvailability . Busy ;
}
break ;
default :
break ; // no change in the availability
}
break ;
case RunspaceAvailability . Available :
case RunspaceAvailability . AvailableForNestedCommand :
case RunspaceAvailability . RemoteDebug :
case RunspaceAvailability . Busy :
switch ( runspaceState )
{
case RunspaceState . Closing :
case RunspaceState . Closed :
case RunspaceState . Broken :
case RunspaceState . Disconnected :
this . RunspaceAvailability = RunspaceAvailability . None ;
break ;
default :
break ; // no change in the availability
}
break ;
default :
Diagnostics . Assert ( false , "Invalid RunspaceAvailability" );
break ;
}
if ( raiseEvent && this . RunspaceAvailability != oldAvailability )
{
OnAvailabilityChanged ( new RunspaceAvailabilityEventArgs ( this . RunspaceAvailability ));
}
}
/// <summary>
/// Used to update the runspace availability from Enter/ExitNestedPrompt and the debugger
/// </summary>
internal void UpdateRunspaceAvailability ( RunspaceAvailability availability , bool raiseEvent )
{
RunspaceAvailability oldAvailability = this . RunspaceAvailability ;
this . RunspaceAvailability = availability ;
if ( raiseEvent && this . RunspaceAvailability != oldAvailability )
{
OnAvailabilityChanged ( new RunspaceAvailabilityEventArgs ( this . RunspaceAvailability ));
}
}
/// <summary>
/// Raises the AvailabilityChanged event
/// </summary>
internal void RaiseAvailabilityChangedEvent ( RunspaceAvailability availability )
{
OnAvailabilityChanged ( new RunspaceAvailabilityEventArgs ( availability ));
}
#endregion events
#region Public static methods
/// <summary>
/// Queries the server for disconnected runspaces and creates an array of runspace
/// objects associated with each disconnected runspace on the server. Each
/// runspace object in the returned array is in the Disconnected state and can be
/// connected to the server by calling the Connect() method on the runspace.
/// </summary>
/// <param name="connectionInfo">Connection object for the target server.</param>
/// <returns>Array of Runspace objects each in the Disconnected state.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspaces")]
public static Runspace [] GetRunspaces ( RunspaceConnectionInfo connectionInfo )
{
return GetRunspaces ( connectionInfo , null , null );
}
/// <summary>
/// Queries the server for disconnected runspaces and creates an array of runspace
/// objects associated with each disconnected runspace on the server. Each
/// runspace object in the returned array is in the Disconnected state and can be
/// connected to the server by calling the Connect() method on the runspace.
/// </summary>
/// <param name="connectionInfo">Connection object for the target server.</param>
/// <param name="host">Client host object.</param>
/// <returns>Array of Runspace objects each in the Disconnected state.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspaces")]
public static Runspace [] GetRunspaces ( RunspaceConnectionInfo connectionInfo , PSHost host )
{
return GetRunspaces ( connectionInfo , host , null );
}
/// <summary>
/// Queries the server for disconnected runspaces and creates an array of runspace
/// objects associated with each disconnected runspace on the server. Each
/// runspace object in the returned array is in the Disconnected state and can be
/// connected to the server by calling the Connect() method on the runspace.
/// </summary>
/// <param name="connectionInfo">Connection object for the target server.</param>
/// <param name="host">Client host object.</param>
/// <param name="typeTable">TypeTable object.</param>
/// <returns>Array of Runspace objects each in the Disconnected state.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspaces")]
public static Runspace [] GetRunspaces ( RunspaceConnectionInfo connectionInfo , PSHost host , TypeTable typeTable )
{
return RemoteRunspace . GetRemoteRunspaces ( connectionInfo , host , typeTable );
}
/// <summary>
/// Returns a single disconnected Runspace object targeted to the remote computer and remote
/// session as specified by the connection, session Id, and command Id parameters.
/// </summary>
/// <param name="connectionInfo">Connection object for the target server.</param>
/// <param name="sessionId">Id of a disconnected remote session on the target server.</param>
/// <param name="commandId">Optional Id of a disconnected command running in the disconnected remote session on the target server.</param>
/// <param name="host">Optional client host object.</param>
/// <param name="typeTable">Optional TypeTable object.</param>
/// <returns>Disconnected runspace corresponding to the provided session Id.</returns>
public static Runspace GetRunspace ( RunspaceConnectionInfo connectionInfo , Guid sessionId , Guid ? commandId , PSHost host , TypeTable typeTable )
{
return RemoteRunspace . GetRemoteRunspace ( connectionInfo , sessionId , commandId , host , typeTable );
}
#endregion
#region public Disconnect - Connect methods
/// <summary>
/// Disconnects the runspace synchronously.
/// </summary>
/// <remarks>
/// Disconnects the remote runspace and any running command from the server
/// machine. Any data generated by the running command on the server is
/// cached on the server machine. This runspace object goes to the disconnected
/// state. This object can be reconnected to the server by calling the
/// Connect() method.
/// If the remote runspace on the server remains disconnected for the IdleTimeout
/// value (as defined in the WSManConnectionInfo object) then it is closed and
/// torn down on the server.
/// </remarks>
/// <exception cref="InvalidRunspaceStateException">
/// RunspaceState is not Opened.
/// </exception>
public abstract void Disconnect ();
/// <summary>
/// Disconnects the runspace asynchronously.
/// </summary>
/// <remarks>
/// Disconnects the remote runspace and any running command from the server
/// machine. Any data generated by the running command on the server is
/// cached on the server machine. This runspace object goes to the disconnected
/// state. This object can be reconnected to the server by calling the
/// Connect() method.
/// If the remote runspace on the server remains disconnected for the IdleTimeout
/// value (as defined in the WSManConnectionInfo object) then it is closed and
/// torn down on the server.
/// </remarks>
/// <exception cref="InvalidRunspaceStateException">
/// RunspaceState is not Opened.
/// </exception>
public abstract void DisconnectAsync ();
/// <summary>
/// Connects the runspace to its remote counterpart synchronously.
/// </summary>
/// <remarks>
/// Connects the runspace object to its corresponding runspace on the target
/// server machine. The target server machine is identified by the connection
/// object passed in during construction. The remote runspace is identified
/// by the internal runspace Guid value.
/// </remarks>
/// <exception cref="InvalidRunspaceStateException">
/// RunspaceState is not Disconnected.
/// </exception>
public abstract void Connect ();
/// <summary>
/// Connects a runspace to its remote counterpart asynchronously.
/// </summary>
/// <remarks>
/// Connects the runspace object to its corresponding runspace on the target
/// server machine. The target server machine is identified by the connection
/// object passed in during construction. The remote runspace is identified
/// by the internal runspace Guid value.
/// </remarks>
/// <exception cref="InvalidRunspaceStateException">
/// RunspaceState is not Disconnected.
/// </exception>
public abstract void ConnectAsync ();
/// <summary>
/// Creates a PipeLine object in the disconnected state for the currently disconnected
/// remote running command associated with this runspace.
/// </summary>
/// <returns>Pipeline object in disconnected state.</returns>
public abstract Pipeline CreateDisconnectedPipeline ();
/// <summary>
/// Creates a PowerShell object in the disconnected state for the currently disconnected
/// remote running command associated with this runspace.
/// </summary>
/// <returns>PowerShell object in disconnected state.</returns>
public abstract PowerShell CreateDisconnectedPowerShell ();
/// <summary>
/// Returns Runspace capabilities.
/// </summary>
/// <returns>RunspaceCapability</returns>
public abstract RunspaceCapability GetCapabilities ();
#endregion
#region methods
/// <summary>
/// Opens the runspace synchronously. Runspace must be opened before it can be used.
/// </summary>
/// <exception cref="InvalidRunspaceStateException">
/// RunspaceState is not BeforeOpen
/// </exception>
public abstract void Open ();
/// <summary>
/// Open the runspace Asynchronously.
/// </summary>
/// <exception cref="InvalidRunspaceStateException">
/// RunspaceState is not BeforeOpen
/// </exception>
public abstract void OpenAsync ();
/// <summary>
/// Close the runspace synchronously.
/// </summary>
/// <remarks>
/// Attempts to execute pipelines after a call to close will fail.
/// </remarks>
/// <exception cref="InvalidRunspaceStateException">
/// RunspaceState is BeforeOpen or Opening
/// </exception>
public abstract void Close ();
/// <summary>
/// Close the runspace Asynchronously.
/// </summary>
/// <remarks>
/// Attempts to execute pipelines after a call to
/// close will fail.
/// </remarks>
/// <exception cref="InvalidRunspaceStateException">
/// RunspaceState is BeforeOpen or Opening
/// </exception>
public abstract void CloseAsync ();
/// <summary>
/// Create an empty pipeline
/// </summary>
/// <returns>An empty pipeline</returns>
public abstract Pipeline CreatePipeline ();
/// <summary>
/// Creates a pipeline for specified command string
/// </summary>
/// <param name="command">A valid command string</param>
/// <returns>
/// A pipline pre-filled with a <see cref="Command"/> object for specified command parameter.
/// </returns>
/// <exception cref="ArgumentNullException">
/// command is null
/// </exception>
public abstract Pipeline CreatePipeline ( string command );
/// <summary>
/// Create a pipeline from a command string.
/// </summary>
/// <param name="command">A valid command string</param>
/// <param name="addToHistory">if true command is added to history</param>
/// <returns>
/// A pipline pre-filled with a <see cref="Command"/> object for specified command parameter.
/// </returns>
/// <exception cref="ArgumentNullException">
/// command is null
/// </exception>
public abstract Pipeline CreatePipeline ( string command , bool addToHistory );
/// <summary>
/// Creates a nested pipeline.
/// </summary>
/// <remarks>
/// Nested pipelines are needed for nested prompt scenario. Nested
/// prompt requires that we execute new pipelines( child pipelines)
/// while current pipeline (lets call it parent pipeline) is blocked.
/// </remarks>
public abstract Pipeline CreateNestedPipeline ();
/// <summary>
/// Creates a nested pipeline.
/// </summary>
/// <param name="command">A valid command string</param>
/// <param name="addToHistory">if true command is added to history</param>
/// <returns>
/// A pipline pre-filled with Command specified in commandString.
/// </returns>
/// <exception cref="ArgumentNullException">
/// command is null
/// </exception>
public abstract Pipeline CreateNestedPipeline ( string command , bool addToHistory );
/// <summary>
/// Returns the currently executing pipeline, or null if no pipeline is executing
/// </summary>
internal abstract Pipeline GetCurrentlyRunningPipeline ();
/// <summary>
/// Private data to be used by applications built on top of PowerShell.
///
/// Local runspace is created with application private data set to an empty <see cref="PSPrimitiveDictionary"/>.
///
/// Remote runspace gets its application private data from the server (set when creating a remote runspace pool)
/// Calling this method on a remote runspace will block until the data is received from the server.
/// The server will send application private data before reaching <see cref="RunspacePoolState.Opened"/> state.
///
/// Runspaces that are part of a <see cref="RunspacePool"/> inherit application private data from the pool.
/// </summary>
public abstract PSPrimitiveDictionary GetApplicationPrivateData ();
/// <summary>
/// A method that runspace pools can use to propagate application private data into runspaces
/// </summary>
/// <param name="applicationPrivateData"></param>
internal abstract void SetApplicationPrivateData ( PSPrimitiveDictionary applicationPrivateData );
/// <summary>
/// Push a running PowerShell onto the stack.
/// </summary>
/// <param name="ps">PowerShell</param>
internal void PushRunningPowerShell ( PowerShell ps )
{
Dbg . Assert ( ps != null , "Caller should not pass in null reference." );
lock ( _syncObject )
{
_runningPowerShells . Push ( ps );
if ( _runningPowerShells . Count == 1 )
{
_baseRunningPowerShell = ps ;
}
}
}
/// <summary>
/// Pop the currently running PowerShell from stack.
/// </summary>
/// <returns>PowerShell</returns>
internal PowerShell PopRunningPowerShell ()
{
lock ( _syncObject )
{
int count = _runningPowerShells . Count ;
if ( count > 0 )
{
if ( count == 1 ) { _baseRunningPowerShell = null ; }
return _runningPowerShells . Pop ();
}
}
return null ;
}
internal PowerShell GetCurrentBasePowerShell ()
{
return _baseRunningPowerShell ;
}
#endregion methods
#region SessionStateProxy
/// <summary>
/// Gets session state proxy
/// </summary>
public SessionStateProxy SessionStateProxy
{
get
{
return GetSessionStateProxy ();
}
}
internal abstract SessionStateProxy GetSessionStateProxy ();
#endregion SessionStateProxy
#region IDisposable Members
/// <summary>
/// Disposes this runspace instance. Dispose will close the runspace if not closed already.
/// </summary>
public void Dispose ()
{
Dispose ( true );
GC . SuppressFinalize ( this );
}
/// <summary>
/// Protected dispose which can be overridden by derived classes.
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose ( bool disposing )
{
lock ( s_syncObject )
{
s_runspaceDictionary . Remove ( Id );
}
}
#endregion IDisposable Members
/// <summary>
/// Gets the execution context
/// </summary>
internal abstract System . Management . Automation . ExecutionContext GetExecutionContext
{
get ;
}
/// <summary>
/// Returns true if the internal host is in a nested prompt
/// </summary>
internal abstract bool InNestedPrompt
{
get ;
}
/// <summary>
/// Gets the debugger
/// </summary>
public virtual Debugger Debugger
{
get
{
var context = GetExecutionContext ;
return ( context != null ) ? context . Debugger : null ;
}
}
/// <summary>
/// InternalDebugger
/// </summary>
internal Debugger InternalDebugger
{
get ;
set ;
}
/// <summary>
/// Gets the event manager
/// </summary>
public abstract PSEventManager Events
{
get ;
}
#if ! CORECLR // Transaction Not Supported On CSS
/// <summary>
/// Sets the base transaction for the runspace; any transactions created on this runspace will be nested to this instance
/// </summary>
///<param name="transaction">The base transaction</param>
///<remarks>This overload uses RollbackSeverity.Error; i.e. the transaction will be rolled back automatically on a non-terminating error or worse</remarks>
public void SetBaseTransaction ( System . Transactions . CommittableTransaction transaction )
{
this . ExecutionContext . TransactionManager . SetBaseTransaction ( transaction , RollbackSeverity . Error );
}
/// <summary>
/// Sets the base transaction for the runspace; any transactions created on this runspace will be nested to this instance
/// </summary>
///<param name="transaction">The base transaction</param>
///<param name="severity">The severity of error that causes PowerShell to automatically rollback the transaction</param>
///
public void SetBaseTransaction ( System . Transactions . CommittableTransaction transaction , RollbackSeverity severity )
{
this . ExecutionContext . TransactionManager . SetBaseTransaction ( transaction , severity );
}
/// <summary>
/// Clears the transaction set by SetBaseTransaction()
/// </summary>
///
public void ClearBaseTransaction ()
{
this . ExecutionContext . TransactionManager . ClearBaseTransaction ();
}
#endif
/// <summary>
/// Resets the variable table for the runspace to the default state.
/// </summary>
public virtual void ResetRunspaceState ()
{
throw new NotImplementedException ( "ResetRunspaceState" );
}
// Used for pipeline id generation.
private long _pipelineIdSeed ;
//Generate pipeline id unique to this runspace
internal long GeneratePipelineId ()
{
return System . Threading . Interlocked . Increment ( ref _pipelineIdSeed );
}
}
/// <summary>
/// This class provides subset of functionality provided by
/// session state.
/// </summary>
public class SessionStateProxy
{
internal SessionStateProxy ()
{
}
2016-07-29 13:02:49 -07:00
private RunspaceBase _runspace ;
2016-03-30 14:20:52 -07:00
internal SessionStateProxy ( RunspaceBase runspace )
{
Dbg . Assert ( runspace != null , "Caller should validate the parameter" );
_runspace = runspace ;
}
/// <summary>
/// Set a variable in session state.
/// </summary>
///
/// <param name="name">
/// The name of the item to set.
/// </param>
///
/// <param name="value">
/// The new value of the item being set.
/// </param>
///
/// <exception cref="ArgumentNullException">
/// name is null
/// </exception>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual void SetVariable ( string name , object value )
{
if ( name == null )
{
throw PSTraceSource . NewArgumentNullException ( "name" );
}
_runspace . SetVariable ( name , value );
}
/// <summary>
/// Get a variable out of session state.
/// </summary>
///
/// <param name="name">
/// name of variable to look up
/// </param>
///
/// <returns>
/// The value of the specified variable.
/// </returns>
///
/// <exception cref="ArgumentNullException">
/// name is null
/// </exception>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual object GetVariable ( string name )
{
if ( name == null )
{
throw PSTraceSource . NewArgumentNullException ( "name" );
}
if ( name . Equals ( string . Empty ))
{
return null ;
}
return _runspace . GetVariable ( name );
}
/// <summary>
/// Get the list of applications out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual List < string > Applications
{
get
{
return _runspace . Applications ;
}
}
/// <summary>
/// Get the list of scripts out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual List < string > Scripts
{
get
{
return _runspace . Scripts ;
}
}
/// <summary>
/// Get the APIs to access drives out of session state
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual DriveManagementIntrinsics Drive
{
get { return _runspace . Drive ; }
}
/// <summary>
/// Get/Set the language mode out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual PSLanguageMode LanguageMode
{
get { return _runspace . LanguageMode ; }
set { _runspace . LanguageMode = value ; }
}
/// <summary>
/// Get the module info out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
2016-07-29 13:02:49 -07:00
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Justification = "Shipped this way in V2 before becoming virtual.")]
2016-03-30 14:20:52 -07:00
public virtual PSModuleInfo Module
{
2016-07-29 13:02:49 -07:00
get { return _runspace . Module ; }
2016-03-30 14:20:52 -07:00
}
/// <summary>
/// Get the APIs to access paths and locations out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual PathIntrinsics Path
{
get { return _runspace . PathIntrinsics ; }
}
/// <summary>
/// Get the APIs to access a provider out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual CmdletProviderManagementIntrinsics Provider
{
get { return _runspace . Provider ; }
}
/// <summary>
/// Get the APIs to access variables out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual PSVariableIntrinsics PSVariable
{
get { return _runspace . PSVariable ; }
}
/// <summary>
/// Get the APIs to build script blocks and execute script out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual CommandInvocationIntrinsics InvokeCommand
{
get { return _runspace . InvokeCommand ; }
}
/// <summary>
/// Gets the instance of the provider interface APIs out of session state.
/// </summary>
///
/// <exception cref="InvalidRunspaceStateException">
/// Runspace is not open.
/// </exception>
///
/// <exception cref="InvalidOperationException">
/// Another SessionStateProxy call or another pipeline is in progress.
/// </exception>
public virtual ProviderIntrinsics InvokeProvider
{
get { return _runspace . InvokeProvider ; }
}
}
}