예제 #1
0
 private void ConnectSessionToHost(PSSession session, PSRemotingJob job = null)
 {
     RemoteRunspace runspace = session.Runspace as RemoteRunspace;
     if (job != null)
     {
         lock (this._syncObject)
         {
             this._job = job;
         }
         using (job)
         {
             Job job2 = job.ChildJobs[0];
             job.ConnectJobs();
             do
             {
                 job2.Results.WaitHandle.WaitOne();
                 foreach (PSStreamObject obj2 in job2.ReadAll())
                 {
                     if (obj2 != null)
                     {
                         obj2.WriteStreamObject(this, false);
                     }
                 }
             }
             while (!job.IsFinishedState(job.JobStateInfo.State));
         }
         lock (this._syncObject)
         {
             this._job = null;
         }
     }
     else if (runspace.RemoteCommand != null)
     {
         lock (this._syncObject)
         {
             this._remotePipeline = (RemotePipeline) session.Runspace.CreateDisconnectedPipeline();
         }
         using (this._remotePipeline)
         {
             this._remotePipeline.ConnectAsync();
             runspace.RunspacePool.RemoteRunspacePoolInternal.ConnectCommands = null;
             while (!this._remotePipeline.Output.EndOfPipeline)
             {
                 if (this._stopProcessing)
                 {
                     break;
                 }
                 this._remotePipeline.Output.WaitHandle.WaitOne();
                 while (this._remotePipeline.Output.Count > 0)
                 {
                     if (this._stopProcessing)
                     {
                         continue;
                     }
                     PSObject psObject = this._remotePipeline.Output.Read();
                     this.WriteRemoteObject(psObject, session);
                 }
             }
             if (this._remotePipeline.Error.Count > 0)
             {
                 while (!this._remotePipeline.Error.EndOfPipeline)
                 {
                     object obj4 = this._remotePipeline.Error.Read();
                     if (obj4 is Collection<ErrorRecord>)
                     {
                         Collection<ErrorRecord> collection = (Collection<ErrorRecord>) obj4;
                         foreach (ErrorRecord record in collection)
                         {
                             base.WriteError(record);
                         }
                     }
                     else if (obj4 is ErrorRecord)
                     {
                         base.WriteError((ErrorRecord) obj4);
                     }
                 }
             }
             this._remotePipeline.PipelineFinishedEvent.WaitOne();
             if (this._remotePipeline.PipelineStateInfo.State == PipelineState.Failed)
             {
                 string pipelineFailedWithoutReason;
                 Exception reason = this._remotePipeline.PipelineStateInfo.Reason;
                 if ((reason != null) && !string.IsNullOrEmpty(reason.Message))
                 {
                     pipelineFailedWithoutReason = StringUtil.Format(RemotingErrorIdStrings.PipelineFailedWithReason, reason.Message);
                 }
                 else
                 {
                     pipelineFailedWithoutReason = RemotingErrorIdStrings.PipelineFailedWithoutReason;
                 }
                 ErrorRecord errorRecord = new ErrorRecord(new RuntimeException(pipelineFailedWithoutReason, reason), "ReceivePSSessionPipelineFailed", ErrorCategory.OperationStopped, this._remotePipeline);
                 base.WriteError(errorRecord);
             }
         }
         lock (this._syncObject)
         {
             this._remotePipeline = null;
         }
     }
 }
예제 #2
0
        /// <summary>
        /// Connects session, retrieves command output data and writes to host.
        /// </summary>
        /// <param name="session">PSSession object.</param>
        /// <param name="job">Job object associated with session.</param>
        private void ConnectSessionToHost(PSSession session, PSRemotingJob job = null)
        {
            RemoteRunspace remoteRunspace = session.Runspace as RemoteRunspace;
            Dbg.Assert(remoteRunspace != null, "PS sessions can only contain RemoteRunspace type.");

            if (job != null)
            {
                // If we have a job object associated with the session then this means
                // the user explicitly chose to connect and return data synchronously.

                // Reconnect the job object and stream data to host.
                lock (_syncObject) { _job = job; _stopPipelineReceive = new ManualResetEvent(false); }
                using (_stopPipelineReceive)
                using (job)
                {
                    Job childJob = job.ChildJobs[0];
                    job.ConnectJobs();
                    if (CheckForDebugMode(session, true)) { return; }
                    do
                    {
                        // Retrieve and display results from child job as they become
                        // available.
                        int index = WaitHandle.WaitAny(new WaitHandle[] {
                            _stopPipelineReceive,
                            childJob.Results.WaitHandle });

                        foreach (var result in childJob.ReadAll())
                        {
                            if (result != null)
                            {
                                result.WriteStreamObject(this);
                            }
                        }

                        if (index == 0)
                        {
                            WriteDebugStopWarning();
                            return;
                        }
                    }
                    while (!job.IsFinishedState(job.JobStateInfo.State));
                }
                lock (_syncObject) { _job = null; _stopPipelineReceive = null; }

                return;
            }

            // Otherwise this must be a new disconnected session object that has a running command 
            // associated with it.
            if (remoteRunspace.RemoteCommand == null)
            {
                // There is no associated running command for this runspace, so we cannot proceed.
                // Check to see if session is in debug mode.
                CheckForDebugMode(session, false);
                return;
            }

            // Create a RemotePipeline object for this command and attempt to connect.
            lock (_syncObject)
            {
                _remotePipeline = (RemotePipeline)session.Runspace.CreateDisconnectedPipeline();
                _stopPipelineReceive = new ManualResetEvent(false);
            }
            using (_stopPipelineReceive)
            {
                using (_remotePipeline)
                {
                    // Connect to remote running command.
                    ManualResetEvent pipelineConnectedEvent = new ManualResetEvent(false);
                    using (pipelineConnectedEvent)
                    {
                        _remotePipeline.StateChanged += (sender, args) =>
                            {
                                if (pipelineConnectedEvent != null &&
                                    (args.PipelineStateInfo.State == PipelineState.Running ||
                                     args.PipelineStateInfo.State == PipelineState.Stopped ||
                                     args.PipelineStateInfo.State == PipelineState.Failed))
                                {
                                    pipelineConnectedEvent.Set();
                                }
                            };
                        _remotePipeline.ConnectAsync();
                        pipelineConnectedEvent.WaitOne();
                    }
                    pipelineConnectedEvent = null;

                    if (CheckForDebugMode(session, true)) { return; }

                    // Wait for remote command to complete, while writing any available data.
                    while (!_remotePipeline.Output.EndOfPipeline)
                    {
                        if (_stopProcessing)
                        {
                            break;
                        }

                        int index = WaitHandle.WaitAny(new WaitHandle[] {
                            _stopPipelineReceive,
                            _remotePipeline.Output.WaitHandle });

                        if (index == 0)
                        {
                            WriteDebugStopWarning();
                            return;
                        }

                        while (_remotePipeline.Output.Count > 0)
                        {
                            if (_stopProcessing)
                            {
                                break;
                            }

                            PSObject psObject = _remotePipeline.Output.Read();
                            WriteRemoteObject(psObject, session);
                        }
                    }

                    // Write pipeline object errors.
                    if (_remotePipeline.Error.Count > 0)
                    {
                        while (!_remotePipeline.Error.EndOfPipeline)
                        {
                            object errorObj = _remotePipeline.Error.Read();
                            if (errorObj is Collection<ErrorRecord>)
                            {
                                Collection<ErrorRecord> errorCollection = (Collection<ErrorRecord>)errorObj;
                                foreach (ErrorRecord errorRecord in errorCollection)
                                {
                                    WriteError(errorRecord);
                                }
                            }
                            else if (errorObj is ErrorRecord)
                            {
                                WriteError((ErrorRecord)errorObj);
                            }
                            else
                            {
                                Dbg.Assert(false, "Objects in pipeline Error collection must be ErrorRecord type.");
                            }
                        }
                    }

                    // Wait for pipeline to finish.
                    int wIndex = WaitHandle.WaitAny(new WaitHandle[] {
                            _stopPipelineReceive,
                            _remotePipeline.PipelineFinishedEvent });

                    if (wIndex == 0)
                    {
                        WriteDebugStopWarning();
                        return;
                    }

                    // Set the runspace RemoteCommand to null.  It is not needed anymore and it
                    // allows the runspace to become available after pipeline completes.
                    remoteRunspace.RunspacePool.RemoteRunspacePoolInternal.ConnectCommands = null;

                    // Check for any terminating errors to report.
                    if (_remotePipeline.PipelineStateInfo.State == PipelineState.Failed)
                    {
                        Exception reason = _remotePipeline.PipelineStateInfo.Reason;
                        string msg;
                        if (reason != null && !string.IsNullOrEmpty(reason.Message))
                        {
                            msg = StringUtil.Format(RemotingErrorIdStrings.PipelineFailedWithReason, reason.Message);
                        }
                        else
                        {
                            msg = RemotingErrorIdStrings.PipelineFailedWithoutReason;
                        }

                        ErrorRecord errorRecord = new ErrorRecord(new RuntimeException(msg, reason),
                                                            "ReceivePSSessionPipelineFailed",
                                                            ErrorCategory.OperationStopped,
                                                            _remotePipeline
                                                            );

                        WriteError(errorRecord);
                    }
                }
            }
            lock (_syncObject) { _remotePipeline = null; _stopPipelineReceive = null; }
        }