private IRSPDriverInvoke _psDriverInvoker;  // Handles nested invocation of PS drivers.

        #endregion Private Members

        #region Constructors

#if !CORECLR
        /// <summary>
        /// Default constructor for creating ServerPowerShellDrivers
        /// </summary>
        /// <param name="powershell">decoded powershell object</param>
        /// <param name="extraPowerShell">extra pipeline to be run after <paramref name="powershell"/> completes</param>
        /// <param name="noInput">whether there is input for this powershell</param>
        /// <param name="clientPowerShellId">the client powershell id</param>
        /// <param name="clientRunspacePoolId">the client runspacepool id</param>
        /// <param name="runspacePoolDriver">runspace pool driver 
        /// which is creating this powershell driver</param>
        /// <param name="apartmentState">apartment state for this powershell</param>
        /// <param name="hostInfo">host info using which the host for
        /// this powershell will be constructed</param>
        /// <param name="streamOptions">serialization options for the streams in this powershell</param>
        /// <param name="addToHistory">
        /// true if the command is to be added to history list of the runspace. false, otherwise.
        /// </param>
        /// <param name="rsToUse">
        /// If not null, this Runspace will be used to invoke Powershell.
        /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
        /// </param>
        internal ServerPowerShellDriver(PowerShell powershell, PowerShell extraPowerShell, bool noInput, Guid clientPowerShellId,
            Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
            ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions,
            bool addToHistory, Runspace rsToUse)
            : this(powershell, extraPowerShell, noInput, clientPowerShellId, clientRunspacePoolId, runspacePoolDriver,
                   apartmentState, hostInfo, streamOptions, addToHistory, rsToUse, null)
        {
        }
 internal ServerPowerShellDataStructureHandler(Guid instanceId, Guid runspacePoolId, RemoteStreamOptions remoteStreamOptions, AbstractServerTransportManager transportManager, PowerShell localPowerShell)
 {
     this.clientPowerShellId = instanceId;
     this.clientRunspacePoolId = runspacePoolId;
     this.transportManager = transportManager;
     this.streamSerializationOptions = remoteStreamOptions;
     transportManager.Closing += new EventHandler(this.HandleTransportClosing);
     if (localPowerShell != null)
     {
         localPowerShell.RunspaceAssigned += new EventHandler<PSEventArgs<Runspace>>(this.LocalPowerShell_RunspaceAssigned);
     }
 }
 internal ServerPowerShellDataStructureHandler CreatePowerShellDataStructureHandler(Guid instanceId, Guid runspacePoolId, RemoteStreamOptions remoteStreamOptions, PowerShell localPowerShell)
 {
     AbstractServerTransportManager transportManager = this.transportManager;
     if (instanceId != Guid.Empty)
     {
         transportManager = this.transportManager.GetCommandTransportManager(instanceId);
     }
     ServerPowerShellDataStructureHandler handler = new ServerPowerShellDataStructureHandler(instanceId, runspacePoolId, remoteStreamOptions, transportManager, localPowerShell);
     lock (this.associationSyncObject)
     {
         this.associatedShells.Add(handler.PowerShellId, handler);
     }
     handler.RemoveAssociation += new EventHandler(this.HandleRemoveAssociation);
     return handler;
 }
        internal void StartPowerShellCommand(
            PowerShell powershell,
            Guid powershellId,
            Guid runspacePoolId,
            ServerRunspacePoolDriver runspacePoolDriver,
#if !CORECLR // No ApartmentState In CoreCLR
            ApartmentState apartmentState,
#endif
            ServerRemoteHost remoteHost,
            HostInfo hostInfo,
            RemoteStreamOptions streamOptions,
            bool addToHistory)
        {
            // For nested debugger command processing, invoke command on new local runspace since
            // the root script debugger runspace is unavailable (it is running a PS script or a 
            // workflow function script).
            Runspace runspace = (remoteHost != null) ?
                RunspaceFactory.CreateRunspace(remoteHost) : RunspaceFactory.CreateRunspace();

            runspace.Open();

            try
            {
                powershell.InvocationStateChanged += HandlePowerShellInvocationStateChanged;
                powershell.SetIsNested(false);

                string script = @"
                    param ($Debugger, $Commands, $output)
                    trap { throw $_ }
                    $Debugger.ProcessCommand($Commands, $output)
                    ";

                PSDataCollection<PSObject> output = new PSDataCollection<PSObject>();
                PSCommand Commands = new PSCommand(powershell.Commands);
                powershell.Commands.Clear();
                powershell.AddScript(script).AddParameter("Debugger", this).AddParameter("Commands", Commands).AddParameter("output", output);
                ServerPowerShellDriver driver = new ServerPowerShellDriver(
                    powershell,
                    null,
                    true,
                    powershellId,
                    runspacePoolId,
                    runspacePoolDriver,
#if !CORECLR // No ApartmentState In CoreCLR
                    apartmentState,
#endif
                    hostInfo,
                    streamOptions,
                    addToHistory,
                    runspace,
                    output);

                driver.Start();
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);

                runspace.Close();
                runspace.Dispose();
            }
        }
        /// <summary>
        /// Starts the PowerShell command on the currently pushed Runspace
        /// </summary>
        /// <param name="powershell">PowerShell command or script</param>
        /// <param name="extraPowerShell">PowerShell command to run after first completes</param>
        /// <param name="powershellId">PowerShell Id</param>
        /// <param name="runspacePoolId">RunspacePool Id</param>
        /// <param name="hostInfo">Host Info</param>
        /// <param name="streamOptions">Remote stream options</param>
        /// <param name="noInput">False when input is provided</param>
        /// <param name="addToHistory">Add to history</param>
        private void StartPowerShellCommandOnPushedRunspace(
            PowerShell powershell,
            PowerShell extraPowerShell,
            Guid powershellId,
            Guid runspacePoolId,
            HostInfo hostInfo,
            RemoteStreamOptions streamOptions,
            bool noInput,
            bool addToHistory)
        {
            Runspace runspace = _remoteHost.PushedRunspace;

            ServerPowerShellDriver driver = new ServerPowerShellDriver(
                powershell,
                extraPowerShell,
                noInput,
                powershellId,
                runspacePoolId,
                this,
#if !CORECLR // No ApartmentState In CoreCLR
                ApartmentState.MTA,
#endif
                hostInfo,
                streamOptions,
                addToHistory,
                runspace);

            try
            {
                driver.Start();
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);

                // Pop runspace on error.
                _remoteHost.PopRunspace();

                throw;
            }
        }
        /// <summary>
        /// Default constructor for creating ServerSteppablePipelineDriver...Used by server to concurrently
        /// run 2 pipelines.
        /// </summary>
        /// <param name="powershell">decoded powershell object</param>
        /// <param name="noInput">whether there is input for this powershell</param>
        /// <param name="clientPowerShellId">the client powershell id</param>
        /// <param name="clientRunspacePoolId">the client runspacepool id</param>
        /// <param name="runspacePoolDriver">runspace pool driver 
        /// which is creating this powershell driver</param>
        /// <param name="apartmentState">apartment state for this powershell</param>
        /// <param name="hostInfo">host info using which the host for
        /// this powershell will be constructed</param>
        /// <param name="streamOptions">serialization options for the streams in this powershell</param>
        /// <param name="addToHistory">
        /// true if the command is to be added to history list of the runspace. false, otherwise.
        /// </param>
        /// <param name="rsToUse">
        /// If not null, this Runspace will be used to invoke Powershell.
        /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
        /// </param>
        /// <param name="eventSubscriber">
        /// Steppable pipeline event subscriber
        /// </param>
        /// <param name="powershellInput">input collection of the PowerShell pipeline</param>
        internal ServerSteppablePipelineDriver(PowerShell powershell, bool noInput, Guid clientPowerShellId,
            Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
            ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions,
            bool addToHistory, Runspace rsToUse, ServerSteppablePipelineSubscriber eventSubscriber, PSDataCollection<object> powershellInput)
#endif
        {
            LocalPowerShell = powershell;
            InstanceId = clientPowerShellId;
            RunspacePoolId = clientRunspacePoolId;
            RemoteStreamOptions = streamOptions;
#if !CORECLR // No ApartmentState In CoreCLR
            this.apartmentState = apartmentState;
#endif
            NoInput = noInput;
            _addToHistory = addToHistory;
            _eventSubscriber = eventSubscriber;
            _powershellInput = powershellInput;

            Input = new PSDataCollection<object>();
            InputEnumerator = Input.GetEnumerator();
            Input.ReleaseOnEnumeration = true;

            DataStructureHandler = runspacePoolDriver.DataStructureHandler.CreatePowerShellDataStructureHandler(clientPowerShellId, clientRunspacePoolId, RemoteStreamOptions, null);
            RemoteHost = DataStructureHandler.GetHostAssociatedWithPowerShell(hostInfo, runspacePoolDriver.ServerRemoteHost);

            // subscribe to various data structure handler events
            DataStructureHandler.InputEndReceived += new EventHandler(HandleInputEndReceived);
            DataStructureHandler.InputReceived += new EventHandler<RemoteDataEventArgs<object>>(HandleInputReceived);
            DataStructureHandler.StopPowerShellReceived += new EventHandler(HandleStopReceived);
            DataStructureHandler.HostResponseReceived +=
                new EventHandler<RemoteDataEventArgs<RemoteHostResponse>>(HandleHostResponseReceived);
            DataStructureHandler.OnSessionConnected += new EventHandler(HandleSessionConnected);

            if (rsToUse == null)
            {
                throw PSTraceSource.NewInvalidOperationException(RemotingErrorIdStrings.NestedPipelineMissingRunspace);
            }

            // else, set the runspace pool and invoke this powershell
            LocalPowerShell.Runspace = rsToUse;
            eventSubscriber.SubscribeEvents(this);

            PipelineState = PSInvocationState.NotStarted;
        }
        private PSDataCollection<object> _powershellInput; // input collection of the PowerShell pipeline

        #endregion

#if CORECLR // No ApartmentState In CoreCLR
        /// <summary>
        /// Default constructor for creating ServerSteppablePipelineDriver...Used by server to concurrently
        /// run 2 pipelines.
        /// </summary>
        /// <param name="powershell">decoded powershell object</param>
        /// <param name="noInput">whether there is input for this powershell</param>
        /// <param name="clientPowerShellId">the client powershell id</param>
        /// <param name="clientRunspacePoolId">the client runspacepool id</param>
        /// <param name="runspacePoolDriver">runspace pool driver 
        /// which is creating this powershell driver</param>        
        /// <param name="hostInfo">host info using which the host for
        /// this powershell will be constructed</param>
        /// <param name="streamOptions">serialization options for the streams in this powershell</param>
        /// <param name="addToHistory">
        /// true if the command is to be added to history list of the runspace. false, otherwise.
        /// </param>
        /// <param name="rsToUse">
        /// If not null, this Runspace will be used to invoke Powershell.
        /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
        /// </param>
        /// <param name="eventSubscriber">
        /// Steppable pipeline event subscriber
        /// </param>
        /// <param name="powershellInput">input collection of the PowerShell pipeline</param>
        internal ServerSteppablePipelineDriver(PowerShell powershell, bool noInput, Guid clientPowerShellId,
            Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
            HostInfo hostInfo, RemoteStreamOptions streamOptions,
            bool addToHistory, Runspace rsToUse, ServerSteppablePipelineSubscriber eventSubscriber, PSDataCollection<object> powershellInput)
        /// <summary>
        /// Creates a powershell data structure handler from this runspace pool
        /// </summary>
        /// <param name="instanceId">powershell instance id</param>
        /// <param name="runspacePoolId">runspace pool id</param>
        /// <param name="remoteStreamOptions">remote stream options</param>
        /// <param name="localPowerShell">local PowerShell object</param>
        /// <returns>ServerPowerShellDataStructureHandler</returns>
        internal ServerPowerShellDataStructureHandler CreatePowerShellDataStructureHandler(
            Guid instanceId, Guid runspacePoolId, RemoteStreamOptions remoteStreamOptions, PowerShell localPowerShell)
        {
            // start with pool's transport manager.
            AbstractServerTransportManager cmdTransportManager = _transportManager;

            if (instanceId != Guid.Empty)
            {
                cmdTransportManager = _transportManager.GetCommandTransportManager(instanceId);
                Dbg.Assert(cmdTransportManager.TypeTable != null, "This should be already set in managed C++ code");
            }

            ServerPowerShellDataStructureHandler dsHandler =
                new ServerPowerShellDataStructureHandler(instanceId, runspacePoolId, remoteStreamOptions, cmdTransportManager, localPowerShell);

            lock (_associationSyncObject)
            {
                _associatedShells.Add(dsHandler.PowerShellId, dsHandler);
            }

            dsHandler.RemoveAssociation += new EventHandler(HandleRemoveAssociation);

            return dsHandler;
        }
        /// <summary>
        /// Default constructor for creating ServerPowerShellDrivers
        /// </summary>
        /// <param name="powershell">decoded powershell object</param>
        /// <param name="extraPowerShell">extra pipeline to be run after <paramref name="powershell"/> completes</param>
        /// <param name="noInput">whether there is input for this powershell</param>
        /// <param name="clientPowerShellId">the client powershell id</param>
        /// <param name="clientRunspacePoolId">the client runspacepool id</param>
        /// <param name="runspacePoolDriver">runspace pool driver 
        /// which is creating this powershell driver</param>
        /// <param name="apartmentState">apartment state for this powershell</param>
        /// <param name="hostInfo">host info using which the host for
        /// this powershell will be constructed</param>
        /// <param name="streamOptions">serialization options for the streams in this powershell</param>
        /// <param name="addToHistory">
        /// true if the command is to be added to history list of the runspace. false, otherwise.
        /// </param>
        /// <param name="rsToUse">
        /// If not null, this Runspace will be used to invoke Powershell.
        /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
        /// </param>
        /// <param name="output">
        /// If not null, this is used as another source of output sent to the client.
        /// </param>
        internal ServerPowerShellDriver(PowerShell powershell, PowerShell extraPowerShell, bool noInput, Guid clientPowerShellId,
            Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
            ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions,
            bool addToHistory, Runspace rsToUse, PSDataCollection<PSObject> output)
#endif
        {
            InstanceId = clientPowerShellId;
            RunspacePoolId = clientRunspacePoolId;
            RemoteStreamOptions = streamOptions;
#if !CORECLR // No ApartmentState In CoreCLR
            this.apartmentState = apartmentState;
#endif
            LocalPowerShell = powershell;
            _extraPowerShell = extraPowerShell;
            _localPowerShellOutput = new PSDataCollection<PSObject>();
            _noInput = noInput;
            _addToHistory = addToHistory;
            _psDriverInvoker = runspacePoolDriver;

            DataStructureHandler = runspacePoolDriver.DataStructureHandler.CreatePowerShellDataStructureHandler(clientPowerShellId, clientRunspacePoolId, RemoteStreamOptions, LocalPowerShell);
            _remoteHost = DataStructureHandler.GetHostAssociatedWithPowerShell(hostInfo, runspacePoolDriver.ServerRemoteHost);

            if (!noInput)
            {
                InputCollection = new PSDataCollection<object>();
                InputCollection.ReleaseOnEnumeration = true;
                InputCollection.IdleEvent += new EventHandler<EventArgs>(HandleIdleEvent);
            }

            RegisterPipelineOutputEventHandlers(_localPowerShellOutput);

            if (LocalPowerShell != null)
            {
                RegisterPowerShellEventHandlers(LocalPowerShell);
                _datasent[0] = false;
            }

            if (extraPowerShell != null)
            {
                RegisterPowerShellEventHandlers(extraPowerShell);
                _datasent[1] = false;
            }

            RegisterDataStructureHandlerEventHandlers(DataStructureHandler);

            // set the runspace pool and invoke this powershell
            if (null != rsToUse)
            {
                LocalPowerShell.Runspace = rsToUse;
                if (extraPowerShell != null)
                {
                    extraPowerShell.Runspace = rsToUse;
                }
            }
            else
            {
                LocalPowerShell.RunspacePool = runspacePoolDriver.RunspacePool;
                if (extraPowerShell != null)
                {
                    extraPowerShell.RunspacePool = runspacePoolDriver.RunspacePool;
                }
            }

            if (output != null)
            {
                output.DataAdded += (sender, args) =>
                    {
                        if (_localPowerShellOutput.IsOpen)
                        {
                            var items = output.ReadAll();
                            foreach (var item in items)
                            {
                                _localPowerShellOutput.Add(item);
                            }
                        }
                    };
            }
        }
        /// <summary>
        /// Default constructor for creating ServerPowerShellDataStructureHandler
        /// instance.
        /// </summary>
        /// <param name="instanceId">Powershell instance id.</param>
        /// <param name="runspacePoolId">Runspace pool id.</param>
        /// <param name="remoteStreamOptions">Remote stream options.</param>
        /// <param name="transportManager">Transport manager.</param>
        /// <param name="localPowerShell">Local powershell object.</param>
        internal ServerPowerShellDataStructureHandler(Guid instanceId, Guid runspacePoolId, RemoteStreamOptions remoteStreamOptions,
                                                      AbstractServerTransportManager transportManager, PowerShell localPowerShell)
        {
            _clientPowerShellId         = instanceId;
            _clientRunspacePoolId       = runspacePoolId;
            _transportManager           = transportManager;
            _streamSerializationOptions = remoteStreamOptions;
            transportManager.Closing   += HandleTransportClosing;

            if (localPowerShell != null)
            {
                localPowerShell.RunspaceAssigned += LocalPowerShell_RunspaceAssigned;
            }
        }
 /// <summary>
 /// Default constructor for creating ServerPowerShellDrivers
 /// </summary>
 /// <param name="powershell">decoded powershell object</param>
 /// <param name="extraPowerShell">extra pipeline to be run after <paramref name="powershell"/> completes</param>
 /// <param name="noInput">whether there is input for this powershell</param>
 /// <param name="clientPowerShellId">the client powershell id</param>
 /// <param name="clientRunspacePoolId">the client runspacepool id</param>
 /// <param name="runspacePoolDriver">runspace pool driver 
 /// which is creating this powershell driver</param>        
 /// <param name="hostInfo">host info using which the host for
 /// this powershell will be constructed</param>
 /// <param name="streamOptions">serialization options for the streams in this powershell</param>
 /// <param name="addToHistory">
 /// true if the command is to be added to history list of the runspace. false, otherwise.
 /// </param>
 /// <param name="rsToUse">
 /// If not null, this Runspace will be used to invoke Powershell.
 /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
 /// </param>
 /// <param name="output">
 /// If not null, this is used as another source of output sent to the client.
 /// </param> 
 internal ServerPowerShellDriver(PowerShell powershell, PowerShell extraPowerShell, bool noInput, Guid clientPowerShellId,
     Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
     HostInfo hostInfo, RemoteStreamOptions streamOptions,
     bool addToHistory, Runspace rsToUse, PSDataCollection<PSObject> output)
Beispiel #12
0
        private PSDataCollection <object> _powershellInput; // input collection of the PowerShell pipeline

        #endregion

        /// <summary>
        /// Default constructor for creating ServerSteppablePipelineDriver...Used by server to concurrently
        /// run 2 pipelines.
        /// </summary>
        /// <param name="powershell">Decoded powershell object.</param>
        /// <param name="noInput">Whether there is input for this powershell.</param>
        /// <param name="clientPowerShellId">The client powershell id.</param>
        /// <param name="clientRunspacePoolId">The client runspacepool id.</param>
        /// <param name="runspacePoolDriver">runspace pool driver
        /// which is creating this powershell driver</param>
        /// <param name="apartmentState">Apartment state for this powershell.</param>
        /// <param name="hostInfo">host info using which the host for
        /// this powershell will be constructed</param>
        /// <param name="streamOptions">Serialization options for the streams in this powershell.</param>
        /// <param name="addToHistory">
        /// true if the command is to be added to history list of the runspace. false, otherwise.
        /// </param>
        /// <param name="rsToUse">
        /// If not null, this Runspace will be used to invoke Powershell.
        /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
        /// </param>
        /// <param name="eventSubscriber">
        /// Steppable pipeline event subscriber
        /// </param>
        /// <param name="powershellInput">Input collection of the PowerShell pipeline.</param>
        internal ServerSteppablePipelineDriver(PowerShell powershell, bool noInput, Guid clientPowerShellId,
                                               Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
                                               ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions,
                                               bool addToHistory, Runspace rsToUse, ServerSteppablePipelineSubscriber eventSubscriber, PSDataCollection <object> powershellInput)
        {
            LocalPowerShell     = powershell;
            InstanceId          = clientPowerShellId;
            RunspacePoolId      = clientRunspacePoolId;
            RemoteStreamOptions = streamOptions;
            this.apartmentState = apartmentState;
            NoInput             = noInput;
            _addToHistory       = addToHistory;
            _eventSubscriber    = eventSubscriber;
            _powershellInput    = powershellInput;

            Input                      = new PSDataCollection <object>();
            InputEnumerator            = Input.GetEnumerator();
            Input.ReleaseOnEnumeration = true;

            DataStructureHandler = runspacePoolDriver.DataStructureHandler.CreatePowerShellDataStructureHandler(clientPowerShellId, clientRunspacePoolId, RemoteStreamOptions, null);
            RemoteHost           = DataStructureHandler.GetHostAssociatedWithPowerShell(hostInfo, runspacePoolDriver.ServerRemoteHost);

            // subscribe to various data structure handler events
            DataStructureHandler.InputEndReceived       += HandleInputEndReceived;
            DataStructureHandler.InputReceived          += HandleInputReceived;
            DataStructureHandler.StopPowerShellReceived += HandleStopReceived;
            DataStructureHandler.HostResponseReceived   += HandleHostResponseReceived;
            DataStructureHandler.OnSessionConnected     += HandleSessionConnected;

            if (rsToUse is null)
            {
                throw PSTraceSource.NewInvalidOperationException(RemotingErrorIdStrings.NestedPipelineMissingRunspace);
            }

            // else, set the runspace pool and invoke this powershell
            LocalPowerShell.Runspace = rsToUse;
            eventSubscriber.SubscribeEvents(this);

            PipelineState = PSInvocationState.NotStarted;
        }
Beispiel #13
0
 internal ServerPowerShellDriver(
     PowerShell powershell,
     PowerShell extraPowerShell,
     bool noInput,
     Guid clientPowerShellId,
     Guid clientRunspacePoolId,
     ServerRunspacePoolDriver runspacePoolDriver,
     ApartmentState apartmentState,
     HostInfo hostInfo,
     RemoteStreamOptions streamOptions,
     bool addToHistory,
     Runspace rsToUse)
 {
     this.clientPowerShellId    = clientPowerShellId;
     this.clientRunspacePoolId  = clientRunspacePoolId;
     this.remoteStreamOptions   = streamOptions;
     this.apartmentState        = apartmentState;
     this.localPowerShell       = powershell;
     this.extraPowerShell       = extraPowerShell;
     this.localPowerShellOutput = new PSDataCollection <PSObject>();
     this.noInput      = noInput;
     this.addToHistory = addToHistory;
     if (!noInput)
     {
         this.input = new PSDataCollection <object>();
         this.input.ReleaseOnEnumeration = true;
     }
     this.dsHandler  = runspacePoolDriver.DataStructureHandler.CreatePowerShellDataStructureHandler(this);
     this.remoteHost = this.dsHandler.GetHostAssociatedWithPowerShell(hostInfo, runspacePoolDriver.ServerRemoteHost);
     this.localPowerShellOutput.DataAdded += new EventHandler <DataAddedEventArgs>(this.HandleOutputDataAdded);
     if (this.localPowerShell != null)
     {
         this.localPowerShell.InvocationStateChanged     += new EventHandler <PSInvocationStateChangedEventArgs>(this.HandlePowerShellInvocationStateChanged);
         this.localPowerShell.Streams.Error.DataAdded    += new EventHandler <DataAddedEventArgs>(this.HandleErrorDataAdded);
         this.localPowerShell.Streams.Debug.DataAdded    += new EventHandler <DataAddedEventArgs>(this.HandleDebugAdded);
         this.localPowerShell.Streams.Verbose.DataAdded  += new EventHandler <DataAddedEventArgs>(this.HandleVerboseAdded);
         this.localPowerShell.Streams.Warning.DataAdded  += new EventHandler <DataAddedEventArgs>(this.HandleWarningAdded);
         this.localPowerShell.Streams.Progress.DataAdded += new EventHandler <DataAddedEventArgs>(this.HandleProgressAdded);
     }
     if (extraPowerShell != null)
     {
         extraPowerShell.InvocationStateChanged     += new EventHandler <PSInvocationStateChangedEventArgs>(this.HandlePowerShellInvocationStateChanged);
         extraPowerShell.Streams.Error.DataAdded    += new EventHandler <DataAddedEventArgs>(this.HandleErrorDataAdded);
         extraPowerShell.Streams.Debug.DataAdded    += new EventHandler <DataAddedEventArgs>(this.HandleDebugAdded);
         extraPowerShell.Streams.Verbose.DataAdded  += new EventHandler <DataAddedEventArgs>(this.HandleVerboseAdded);
         extraPowerShell.Streams.Warning.DataAdded  += new EventHandler <DataAddedEventArgs>(this.HandleWarningAdded);
         extraPowerShell.Streams.Progress.DataAdded += new EventHandler <DataAddedEventArgs>(this.HandleProgressAdded);
     }
     this.dsHandler.InputEndReceived       += new EventHandler(this.HandleInputEndReceived);
     this.dsHandler.InputReceived          += new EventHandler <RemoteDataEventArgs <object> >(this.HandleInputReceived);
     this.dsHandler.StopPowerShellReceived += new EventHandler(this.HandleStopReceived);
     this.dsHandler.HostResponseReceived   += new EventHandler <RemoteDataEventArgs <RemoteHostResponse> >(this.HandleHostResponseReceived);
     if (rsToUse != null)
     {
         this.localPowerShell.Runspace = rsToUse;
         if (extraPowerShell == null)
         {
             return;
         }
         extraPowerShell.Runspace = rsToUse;
     }
     else
     {
         this.localPowerShell.RunspacePool = runspacePoolDriver.RunspacePool;
         if (extraPowerShell == null)
         {
             return;
         }
         extraPowerShell.RunspacePool = runspacePoolDriver.RunspacePool;
     }
 }
        private PSDataCollection <object> _powershellInput; // input collection of the PowerShell pipeline

        #endregion

#if CORECLR // No ApartmentState In CoreCLR
        /// <summary>
        /// Default constructor for creating ServerSteppablePipelineDriver...Used by server to concurrently
        /// run 2 pipelines.
        /// </summary>
        /// <param name="powershell">decoded powershell object</param>
        /// <param name="noInput">whether there is input for this powershell</param>
        /// <param name="clientPowerShellId">the client powershell id</param>
        /// <param name="clientRunspacePoolId">the client runspacepool id</param>
        /// <param name="runspacePoolDriver">runspace pool driver
        /// which is creating this powershell driver</param>
        /// <param name="hostInfo">host info using which the host for
        /// this powershell will be constructed</param>
        /// <param name="streamOptions">serialization options for the streams in this powershell</param>
        /// <param name="addToHistory">
        /// true if the command is to be added to history list of the runspace. false, otherwise.
        /// </param>
        /// <param name="rsToUse">
        /// If not null, this Runspace will be used to invoke Powershell.
        /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
        /// </param>
        /// <param name="eventSubscriber">
        /// Steppable pipeline event subscriber
        /// </param>
        /// <param name="powershellInput">input collection of the PowerShell pipeline</param>
        internal ServerSteppablePipelineDriver(PowerShell powershell, bool noInput, Guid clientPowerShellId,
                                               Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
                                               HostInfo hostInfo, RemoteStreamOptions streamOptions,
                                               bool addToHistory, Runspace rsToUse, ServerSteppablePipelineSubscriber eventSubscriber, PSDataCollection <object> powershellInput)
 /// <summary>
 /// Default constructor for creating ServerPowerShellDrivers.
 /// </summary>
 /// <param name="powershell">Decoded powershell object.</param>
 /// <param name="extraPowerShell">Extra pipeline to be run after <paramref name="powershell"/> completes.</param>
 /// <param name="noInput">Whether there is input for this powershell.</param>
 /// <param name="clientPowerShellId">The client powershell id.</param>
 /// <param name="clientRunspacePoolId">The client runspacepool id.</param>
 /// <param name="runspacePoolDriver">runspace pool driver
 /// which is creating this powershell driver</param>
 /// <param name="apartmentState">Apartment state for this powershell.</param>
 /// <param name="hostInfo">host info using which the host for
 /// this powershell will be constructed</param>
 /// <param name="streamOptions">Serialization options for the streams in this powershell.</param>
 /// <param name="addToHistory">
 /// true if the command is to be added to history list of the runspace. false, otherwise.
 /// </param>
 /// <param name="rsToUse">
 /// If not null, this Runspace will be used to invoke Powershell.
 /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
 /// </param>
 internal ServerPowerShellDriver(PowerShell powershell, PowerShell extraPowerShell, bool noInput, Guid clientPowerShellId,
                                 Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
                                 ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions,
                                 bool addToHistory, Runspace rsToUse)
     : this(powershell, extraPowerShell, noInput, clientPowerShellId, clientRunspacePoolId, runspacePoolDriver,
            apartmentState, hostInfo, streamOptions, addToHistory, rsToUse, null)
 {
 }
        /// <summary>
        /// Default constructor for creating ServerPowerShellDrivers.
        /// </summary>
        /// <param name="powershell">Decoded powershell object.</param>
        /// <param name="extraPowerShell">Extra pipeline to be run after <paramref name="powershell"/> completes.</param>
        /// <param name="noInput">Whether there is input for this powershell.</param>
        /// <param name="clientPowerShellId">The client powershell id.</param>
        /// <param name="clientRunspacePoolId">The client runspacepool id.</param>
        /// <param name="runspacePoolDriver">runspace pool driver
        /// which is creating this powershell driver</param>
        /// <param name="apartmentState">Apartment state for this powershell.</param>
        /// <param name="hostInfo">host info using which the host for
        /// this powershell will be constructed</param>
        /// <param name="streamOptions">Serialization options for the streams in this powershell.</param>
        /// <param name="addToHistory">
        /// true if the command is to be added to history list of the runspace. false, otherwise.
        /// </param>
        /// <param name="rsToUse">
        /// If not null, this Runspace will be used to invoke Powershell.
        /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used.
        /// </param>
        /// <param name="output">
        /// If not null, this is used as another source of output sent to the client.
        /// </param>
        internal ServerPowerShellDriver(PowerShell powershell, PowerShell extraPowerShell, bool noInput, Guid clientPowerShellId,
                                        Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver,
                                        ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions,
                                        bool addToHistory, Runspace rsToUse, PSDataCollection <PSObject> output)
        {
            InstanceId             = clientPowerShellId;
            RunspacePoolId         = clientRunspacePoolId;
            RemoteStreamOptions    = streamOptions;
            this.apartmentState    = apartmentState;
            LocalPowerShell        = powershell;
            _extraPowerShell       = extraPowerShell;
            _localPowerShellOutput = new PSDataCollection <PSObject>();
            _noInput         = noInput;
            _addToHistory    = addToHistory;
            _psDriverInvoker = runspacePoolDriver;

            DataStructureHandler = runspacePoolDriver.DataStructureHandler.CreatePowerShellDataStructureHandler(clientPowerShellId, clientRunspacePoolId, RemoteStreamOptions, LocalPowerShell);
            _remoteHost          = DataStructureHandler.GetHostAssociatedWithPowerShell(hostInfo, runspacePoolDriver.ServerRemoteHost);

            if (!noInput)
            {
                InputCollection = new PSDataCollection <object>();
                InputCollection.ReleaseOnEnumeration = true;
                InputCollection.IdleEvent           += HandleIdleEvent;
            }

            RegisterPipelineOutputEventHandlers(_localPowerShellOutput);

            if (LocalPowerShell != null)
            {
                RegisterPowerShellEventHandlers(LocalPowerShell);
                _datasent[0] = false;
            }

            if (extraPowerShell != null)
            {
                RegisterPowerShellEventHandlers(extraPowerShell);
                _datasent[1] = false;
            }

            RegisterDataStructureHandlerEventHandlers(DataStructureHandler);

            // set the runspace pool and invoke this powershell
            if (rsToUse != null)
            {
                LocalPowerShell.Runspace = rsToUse;
                if (extraPowerShell != null)
                {
                    extraPowerShell.Runspace = rsToUse;
                }
            }
            else
            {
                LocalPowerShell.RunspacePool = runspacePoolDriver.RunspacePool;
                if (extraPowerShell != null)
                {
                    extraPowerShell.RunspacePool = runspacePoolDriver.RunspacePool;
                }
            }

            if (output != null)
            {
                output.DataAdded += (sender, args) =>
                {
                    if (_localPowerShellOutput.IsOpen)
                    {
                        var items = output.ReadAll();
                        foreach (var item in items)
                        {
                            _localPowerShellOutput.Add(item);
                        }
                    }
                };
            }
        }