internal PSRemotingChildJob(string remoteCommand, ExecutionCmdletHelper helper, ThrottleManager throttleManager) : base(remoteCommand) { this.hideComputerName = true; this.SyncObject = new object(); base.UsesResultsCollection = true; this.helper = helper; this.remoteRunspace = helper.Pipeline.Runspace; this.remotePipeline = helper.Pipeline as RemotePipeline; this.throttleManager = throttleManager; RemoteRunspace remoteRunspace = this.remoteRunspace as RemoteRunspace; if ((remoteRunspace != null) && (remoteRunspace.RunspaceStateInfo.State == RunspaceState.BeforeOpen)) { remoteRunspace.URIRedirectionReported += new EventHandler<RemoteDataEventArgs<Uri>>(this.HandleURIDirectionReported); } this.AggregateResultsFromHelper(helper); this.RegisterThrottleComplete(throttleManager); }
private RemotePipeline(RemotePipeline pipeline) : this((RemoteRunspace) pipeline.Runspace, null, false, pipeline.IsNested) { this._isSteppable = pipeline._isSteppable; if (pipeline == null) { throw PSTraceSource.NewArgumentNullException("pipeline"); } if (pipeline._disposed) { throw PSTraceSource.NewObjectDisposedException("pipeline"); } this._addToHistory = pipeline._addToHistory; this._historyString = pipeline._historyString; foreach (Command command in pipeline.Commands) { Command item = command.Clone(); base.Commands.Add(item); } }
internal PSInvokeExpressionSyncJob( List <IThrottleOperation> operations, ThrottleManager throttleManager) { this.Results.AddRef(); this.throttleManager = throttleManager; this.RegisterThrottleComplete(this.throttleManager); foreach (IThrottleOperation operation in operations) { ExecutionCmdletHelper helper = operation as ExecutionCmdletHelper; if (helper.Pipeline.Runspace is RemoteRunspace runspace && runspace.RunspaceStateInfo.State == RunspaceState.BeforeOpen) { runspace.URIRedirectionReported += new EventHandler <RemoteDataEventArgs <Uri> >(((PSRemotingChildJob)this).HandleURIDirectionReported); runspace.StateChanged += new EventHandler <RunspaceStateEventArgs>(this.HandleRunspaceStateChanged); } this.helpers.Add(helper); this.AggregateResultsFromHelper(helper); RemotePipeline pipeline = helper.Pipeline as RemotePipeline; this.powershells.Add(pipeline.PowerShell.InstanceId, pipeline.PowerShell); } throttleManager.SubmitOperations(operations); throttleManager.EndSubmitOperations(); }
internal PSRemotingChildJob(ExecutionCmdletHelper helper, ThrottleManager throttleManager, bool aggregateResults = false) { this.hideComputerName = true; this.SyncObject = new object(); base.UsesResultsCollection = true; this.helper = helper; this.remotePipeline = helper.Pipeline as RemotePipeline; this.remoteRunspace = helper.Pipeline.Runspace; this.throttleManager = throttleManager; if (aggregateResults) { this.AggregateResultsFromHelper(helper); } else { this.remotePipeline.StateChanged += new EventHandler<PipelineStateEventArgs>(this.HandlePipelineStateChanged); this.remotePipeline.Output.DataReady += new EventHandler(this.HandleOutputReady); this.remotePipeline.Error.DataReady += new EventHandler(this.HandleErrorReady); } IThrottleOperation operation = helper; operation.OperationComplete += new EventHandler<OperationStateEventArgs>(this.HandleOperationComplete); base.SetJobState(JobState.Disconnected, null); }
internal PSRemotingChildJob(ExecutionCmdletHelper helper, ThrottleManager throttleManager, bool aggregateResults = false) { this.hideComputerName = true; this.SyncObject = new object(); base.UsesResultsCollection = true; this.helper = helper; this.remotePipeline = helper.Pipeline as RemotePipeline; this.remoteRunspace = helper.Pipeline.Runspace; this.throttleManager = throttleManager; if (aggregateResults) { this.AggregateResultsFromHelper(helper); } else { this.remotePipeline.StateChanged += new EventHandler <PipelineStateEventArgs>(this.HandlePipelineStateChanged); this.remotePipeline.Output.DataReady += new EventHandler(this.HandleOutputReady); this.remotePipeline.Error.DataReady += new EventHandler(this.HandleErrorReady); } IThrottleOperation operation = helper; operation.OperationComplete += new EventHandler <OperationStateEventArgs>(this.HandleOperationComplete); base.SetJobState(JobState.Disconnected, null); }
protected void ProcessJobFailure(ExecutionCmdletHelper helper, out Exception failureException, out ErrorRecord failureErrorRecord) { RemotePipeline pipeline = helper.Pipeline as RemotePipeline; RemoteRunspace runspace = pipeline.GetRunspace() as RemoteRunspace; failureException = null; failureErrorRecord = null; if (helper.InternalException != null) { string errorId = "RemotePipelineExecutionFailed"; failureException = helper.InternalException; if ((failureException is InvalidRunspaceStateException) || (failureException is InvalidRunspacePoolStateException)) { errorId = "InvalidSessionState"; if (!string.IsNullOrEmpty(failureException.Source)) { errorId = string.Format(CultureInfo.InvariantCulture, "{0},{1}", new object[] { errorId, failureException.Source }); } } failureErrorRecord = new ErrorRecord(helper.InternalException, errorId, ErrorCategory.OperationStopped, helper); } else if (runspace.RunspaceStateInfo.State == RunspaceState.Broken) { failureException = runspace.RunspaceStateInfo.Reason; object computerName = runspace.ConnectionInfo.ComputerName; string str2 = null; PSRemotingTransportException exception = failureException as PSRemotingTransportException; string fQEIDFromTransportError = WSManTransportManagerUtils.GetFQEIDFromTransportError((exception != null) ? exception.ErrorCode : 0, "PSSessionStateBroken"); if (exception != null) { str2 = "[" + runspace.ConnectionInfo.ComputerName + "] "; if (exception.ErrorCode == -2144108135) { string str4 = PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.URIRedirectionReported, new object[] { exception.Message, "MaximumConnectionRedirectionCount", "PSSessionOption", "AllowRedirection" }); str2 = str2 + str4; } else if (!string.IsNullOrEmpty(exception.Message)) { str2 = str2 + exception.Message; } else if (!string.IsNullOrEmpty(exception.TransportMessage)) { str2 = str2 + exception.TransportMessage; } } if (failureException == null) { failureException = new RuntimeException(PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.RemoteRunspaceOpenUnknownState, new object[] { runspace.RunspaceStateInfo.State })); } failureErrorRecord = new ErrorRecord(failureException, computerName, fQEIDFromTransportError, ErrorCategory.OpenError, null, null, null, null, null, str2, null); } else if (pipeline.PipelineStateInfo.State == PipelineState.Failed) { object targetObject = runspace.ConnectionInfo.ComputerName; failureException = pipeline.PipelineStateInfo.Reason; if (failureException != null) { RemoteException exception2 = failureException as RemoteException; ErrorRecord errorRecord = null; if (exception2 != null) { errorRecord = exception2.ErrorRecord; } else { errorRecord = new ErrorRecord(pipeline.PipelineStateInfo.Reason, "JobFailure", ErrorCategory.OperationStopped, targetObject); } string str5 = ((RemoteRunspace)pipeline.GetRunspace()).ConnectionInfo.ComputerName; Guid instanceId = pipeline.GetRunspace().InstanceId; OriginInfo originInfo = new OriginInfo(str5, instanceId); failureErrorRecord = new RemotingErrorRecord(errorRecord, originInfo); } } }
internal static RemotePipeline ConnectRunningPipeline(RemoteRunspace remoteRunspace) { RemotePipeline cmd = null; if (remoteRunspace.RemoteCommand != null) { // Reconstruct scenario. // Newly connected pipeline object is added to the RemoteRunspace running // pipeline list. cmd = new RemotePipeline(remoteRunspace); } else { // Reconnect scenario. cmd = remoteRunspace.GetCurrentlyRunningPipeline() as RemotePipeline; } // Connect the runspace pipeline so that debugging and output data from // remote server can continue. if (cmd != null && cmd.PipelineStateInfo.State == PipelineState.Disconnected) { using (ManualResetEvent connected = new ManualResetEvent(false)) { cmd.StateChanged += (sender, args) => { if (args.PipelineStateInfo.State != PipelineState.Disconnected) { try { connected.Set(); } catch (ObjectDisposedException) { } } }; cmd.ConnectAsync(); connected.WaitOne(); } } return cmd; }
/// <summary> /// Creates a cloned pipeline from the specified one /// </summary> /// <param name="pipeline">pipeline to clone from</param> /// <remarks>This constructor is private because this will /// only be called from the copy method</remarks> private RemotePipeline(RemotePipeline pipeline) : this((RemoteRunspace)pipeline.Runspace, null, false, pipeline.IsNested) { _isSteppable = pipeline._isSteppable; // NTRAID#Windows Out Of Band Releases-915851-2005/09/13 // the above comment copied from RemotePipelineBase which // originally copied it from PipelineBase if (null == pipeline) { throw PSTraceSource.NewArgumentNullException("pipeline"); } if (pipeline._disposed) { throw PSTraceSource.NewObjectDisposedException("pipeline"); } _addToHistory = pipeline._addToHistory; _historyString = pipeline._historyString; foreach (Command command in pipeline.Commands) { Command clone = command.Clone(); // Attach the cloned Command to this pipeline. Commands.Add(clone); } }
internal void RemoveFromRunningPipelineList(RemotePipeline pipeline) { lock (this._syncRoot) { this._runningPipelines.Remove(pipeline); pipeline.PipelineFinishedEvent.Set(); } }
private PowerShell GetPipelinePowerShell(RemotePipeline pipeline, Guid instanceId) { if (pipeline != null) { return pipeline.PowerShell; } return this.GetPowerShell(instanceId); }
/// <summary> /// Check to see, if there is any other pipeline running in this /// runspace. If not, then add this to the list of pipelines /// </summary> /// <param name="pipeline">pipeline to check and add</param> /// <param name="syncCall">whether this is being called from /// a synchronous method call</param> internal void DoConcurrentCheckAndAddToRunningPipelines(RemotePipeline pipeline, bool syncCall) { //Concurrency check should be done under runspace lock lock (_syncRoot) { if (_bSessionStateProxyCallInProgress == true) { throw PSTraceSource.NewInvalidOperationException(RunspaceStrings.NoPipelineWhenSessionStateProxyInProgress); } //Delegate to pipeline to do check if it is fine to invoke if another //pipeline is running. pipeline.DoConcurrentCheck(syncCall); //Finally add to the list of running pipelines. AddToRunningPipelineList(pipeline); } }
/// <summary> /// Remove the pipeline from list of pipelines in execution. /// </summary> /// <param name="pipeline">Pipeline to remove from the /// list of pipelines in execution</param> /// /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="pipeline"/> is null. /// </exception> internal void RemoveFromRunningPipelineList(RemotePipeline pipeline) { Dbg.Assert(pipeline != null, "caller should validate the parameter"); lock (_syncRoot) { Dbg.Assert(_runspaceStateInfo.State != RunspaceState.BeforeOpen, "Runspace should not be before open when pipeline is running"); //Remove the pipeline to list of Executing pipeline. //Note:_runningPipelines is always accessed with the lock so //there is no need to create a synchronized version of list _runningPipelines.Remove(pipeline); pipeline.PipelineFinishedEvent.Set(); } }
/// <summary> /// Add the pipeline to list of pipelines in execution. /// </summary> /// <param name="pipeline">Pipeline to add to the /// list of pipelines in execution</param> /// /// <exception cref="InvalidRunspaceStateException"> /// Thrown if the runspace is not in the Opened state. /// <see cref="RunspaceState"/>. /// </exception> /// /// <exception cref="ArgumentNullException">Thrown if /// <paramref name="pipeline"/> is null. /// </exception> internal void AddToRunningPipelineList(RemotePipeline pipeline) { Dbg.Assert(pipeline != null, "caller should validate the parameter"); lock (_syncRoot) { if (_bypassRunspaceStateCheck == false && _runspaceStateInfo.State != RunspaceState.Opened && _runspaceStateInfo.State != RunspaceState.Disconnected) // Disconnected runspaces can have running pipelines. { InvalidRunspaceStateException e = new InvalidRunspaceStateException ( StringUtil.Format(RunspaceStrings.RunspaceNotOpenForPipeline, _runspaceStateInfo.State.ToString() ), _runspaceStateInfo.State, RunspaceState.Opened ); if (this.ConnectionInfo != null) { e.Source = this.ConnectionInfo.ComputerName; } throw e; } //Add the pipeline to list of Executing pipeline. //Note:_runningPipelines is always accessed with the lock so //there is no need to create a synchronized version of list _runningPipelines.Add(pipeline); } }
internal void AddToRunningPipelineList(RemotePipeline pipeline) { lock (this._syncRoot) { if ((!this._bypassRunspaceStateCheck && (this._runspaceStateInfo.State != RunspaceState.Opened)) && (this._runspaceStateInfo.State != RunspaceState.Disconnected)) { InvalidRunspaceStateException exception = new InvalidRunspaceStateException(StringUtil.Format(RunspaceStrings.RunspaceNotOpenForPipeline, this._runspaceStateInfo.State.ToString()), this._runspaceStateInfo.State, RunspaceState.Opened); if (this.ConnectionInfo != null) { exception.Source = this.ConnectionInfo.ComputerName; } throw exception; } this._runningPipelines.Add(pipeline); } }
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; } } }
/// <summary> /// Check if anyother pipeline is executing. /// In case of nested pipeline, checks that it is called /// from currently executing pipeline's thread. /// </summary> /// <param name="syncCall">True if method is called from Invoke, false /// if called from InvokeAsync</param> /// <exception cref="InvalidOperationException"> /// 1) A pipeline is already executing. Pipeline cannot execute /// concurrently. /// 2) InvokeAsync is called on nested pipeline. Nested pipeline /// cannot be executed Asynchronously. /// 3) Attempt is made to invoke a nested pipeline directly. Nested /// pipeline must be invoked from a running pipeline. /// </exception> internal void DoConcurrentCheck(bool syncCall) { RemotePipeline currentPipeline = (RemotePipeline)((RemoteRunspace)_runspace).GetCurrentlyRunningPipeline(); if (_isNested == false) { if (currentPipeline == null && ((RemoteRunspace)_runspace).RunspaceAvailability != RunspaceAvailability.Busy && ((RemoteRunspace)_runspace).RunspaceAvailability != RunspaceAvailability.RemoteDebug) { // We can add a new pipeline to the runspace only if it is // available (not busy). return; } if (currentPipeline == null && ((RemoteRunspace)_runspace).RemoteCommand != null && _connectCmdInfo != null && Guid.Equals(((RemoteRunspace)_runspace).RemoteCommand.CommandId, _connectCmdInfo.CommandId)) { // Connect case. We can add a pipeline to a busy runspace when // that pipeline represents the same command as is currently // running. return; } if (currentPipeline != null && ReferenceEquals(currentPipeline, this)) { // Reconnect case. We can add a pipeline to a busy runspace when the // pipeline is the same (reconnecting). return; } if (!_isSteppable) { throw PSTraceSource.NewInvalidOperationException( RunspaceStrings.ConcurrentInvokeNotAllowed); } } else { if (_performNestedCheck) { if (_isSteppable) { return; } if (syncCall == false) { throw PSTraceSource.NewInvalidOperationException( RunspaceStrings.NestedPipelineInvokeAsync); } if (currentPipeline == null) { if (!_isSteppable) { throw PSTraceSource.NewInvalidOperationException( RunspaceStrings.NestedPipelineNoParentPipeline); } } } } }
internal void DoConcurrentCheckAndAddToRunningPipelines(RemotePipeline pipeline, bool syncCall) { lock (this._syncRoot) { if (this._bSessionStateProxyCallInProgress) { throw PSTraceSource.NewInvalidOperationException("RunspaceStrings", "NoPipelineWhenSessionStateProxyInProgress", new object[0]); } pipeline.DoConcurrentCheck(syncCall); this.AddToRunningPipelineList(pipeline); } }