private void HandleInvocationStateInfoReceived(object sender, RemoteDataEventArgs <PSInvocationStateInfo> eventArgs) { using (tracer.TraceEventHandlers()) { PSInvocationStateInfo data = eventArgs.Data; if (data.State == PSInvocationState.Disconnected) { this.SetStateInfo(data); } else if (((data.State == PSInvocationState.Stopped) || (data.State == PSInvocationState.Failed)) || (data.State == PSInvocationState.Completed)) { this.UnblockCollections(); if (this.stopCalled) { this.stopCalled = false; this.stateInfoQueue.Enqueue(new PSInvocationStateInfo(PSInvocationState.Stopped, data.Reason)); this.CheckAndCloseRunspaceAfterStop(data.Reason); } else { this.stateInfoQueue.Enqueue(data); } this.dataStructureHandler.CloseConnectionAsync(null); } } }
internal void ProcessDisconnect(RunspacePoolStateInfo rsStateInfo) { PSInvocationStateInfo data = new PSInvocationStateInfo(PSInvocationState.Disconnected, (rsStateInfo != null) ? rsStateInfo.Reason : null); this.InvocationStateInfoReceived.SafeInvoke <RemoteDataEventArgs <PSInvocationStateInfo> >(this, new RemoteDataEventArgs <PSInvocationStateInfo>(data)); Interlocked.CompareExchange(ref this.connectionState, 3, 1); }
private static Exception CheckInvocationStateInfoForException(PSInvocationStateInfo invokeStateInfo) { if (invokeStateInfo.State != PSInvocationState.Failed) { return(null); } else { return(invokeStateInfo.Reason); } }
private static SessionStateChangedEventArgs TranslateInvocationStateInfo(PSInvocationStateInfo invocationState) { PowerShellContextState newState = PowerShellContextState.Unknown; PowerShellExecutionResult executionResult = PowerShellExecutionResult.NotFinished; switch (invocationState.State) { case PSInvocationState.NotStarted: newState = PowerShellContextState.NotStarted; break; case PSInvocationState.Failed: newState = PowerShellContextState.Ready; executionResult = PowerShellExecutionResult.Failed; break; case PSInvocationState.Disconnected: // TODO: Any extra work to do in this case? // TODO: Is this a unique state that can be re-connected? newState = PowerShellContextState.Disposed; executionResult = PowerShellExecutionResult.Stopped; break; case PSInvocationState.Running: newState = PowerShellContextState.Running; break; case PSInvocationState.Completed: newState = PowerShellContextState.Ready; executionResult = PowerShellExecutionResult.Completed; break; case PSInvocationState.Stopping: // TODO: Collapse this so that the result shows that execution was aborted newState = PowerShellContextState.Aborting; break; case PSInvocationState.Stopped: newState = PowerShellContextState.Ready; executionResult = PowerShellExecutionResult.Aborted; break; default: newState = PowerShellContextState.Unknown; break; } return (new SessionStateChangedEventArgs( newState, executionResult, invocationState.Reason)); }
private void HandleCloseCompleted(object sender, EventArgs args) { this.dataStructureHandler.RaiseRemoveAssociationEvent(); if (this.stateInfoQueue.Count != 0) { while (this.stateInfoQueue.Count > 0) { PSInvocationStateInfo stateInfo = this.stateInfoQueue.Dequeue(); this.SetStateInfo(stateInfo); } } else if (!this.IsFinished(this.shell.InvocationStateInfo.State)) { RemoteSessionStateEventArgs args2 = args as RemoteSessionStateEventArgs; Exception reason = (args2 != null) ? args2.SessionStateInfo.Reason : null; PSInvocationState state = (this.shell.InvocationStateInfo.State == PSInvocationState.Disconnected) ? PSInvocationState.Failed : PSInvocationState.Stopped; this.SetStateInfo(new PSInvocationStateInfo(state, reason)); } }
/// <summary> /// This is need for the state change events that resulted in closing the underlying /// datastructure handler. We cannot send the state back to the upper layers until /// close is completed from the datastructure/transport layer. We have to send /// the terminal state only when we know that underlying datastructure/transport /// is closed. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void HandleCloseCompleted(object sender, EventArgs args) { // if state is completed or failed or stopped, // then the collections need to be closed as // well, else the enumerator will block UnblockCollections(); // close the transport manager when CreateCloseAckPacket is received // otherwise may have race conditions in Server.OutOfProcessMediator dataStructureHandler.RaiseRemoveAssociationEvent(); if (_stateInfoQueue.Count == 0) { // If shell state is not finished on client side and queue is empty // then set state to stopped unless the current state is Disconnected // in which case transition state to failed. if (!IsFinished(shell.InvocationStateInfo.State)) { // If RemoteSessionStateEventArgs are provided then use them to set the // session close reason when setting finished state. RemoteSessionStateEventArgs sessionEventArgs = args as RemoteSessionStateEventArgs; Exception closeReason = (sessionEventArgs != null) ? sessionEventArgs.SessionStateInfo.Reason : null; PSInvocationState finishedState = (shell.InvocationStateInfo.State == PSInvocationState.Disconnected) ? PSInvocationState.Failed : PSInvocationState.Stopped; SetStateInfo(new PSInvocationStateInfo(finishedState, closeReason)); } } else { // Apply queued state changes. while (_stateInfoQueue.Count > 0) { PSInvocationStateInfo stateInfo = _stateInfoQueue.Dequeue(); SetStateInfo(stateInfo); } } }
private void SetJobState(PSInvocationStateInfo invocationStateInfo) { var disposeRunspace = false; System.Enum.TryParse <JobState>(invocationStateInfo.State.ToString(), out JobState jobState); switch (invocationStateInfo.State) { case PSInvocationState.Running: this.SetJobState(JobState.Running); break; case PSInvocationState.Completed: case PSInvocationState.Stopped: case PSInvocationState.Failed: this.SetJobState(jobState, invocationStateInfo.Reason); disposeRunspace = true; break; } if (disposeRunspace) { this.__runspace.Dispose(); } }
/// <summary> /// Set the state information of the client powershell /// </summary> /// <param name="stateInfo">state information to set.</param> internal void SetStateInfo(PSInvocationStateInfo stateInfo) { shell.SetStateChanged(stateInfo); }
/// <summary> /// The invocation state of the server powershell has changed. /// The state of the client powershell is reflected accordingly /// </summary> /// <param name="sender">sender of this event, unused.</param> /// <param name="eventArgs">arguments describing this event.</param> private void HandleInvocationStateInfoReceived(object sender, RemoteDataEventArgs <PSInvocationStateInfo> eventArgs) { using (s_tracer.TraceEventHandlers()) { PSInvocationStateInfo stateInfo = eventArgs.Data; // we should not receive any transient state from // the server Dbg.Assert(!(stateInfo.State == PSInvocationState.Running || stateInfo.State == PSInvocationState.Stopping), "Transient states should not be received from the server"); if (stateInfo.State == PSInvocationState.Disconnected) { SetStateInfo(stateInfo); } else if (stateInfo.State == PSInvocationState.Stopped || stateInfo.State == PSInvocationState.Failed || stateInfo.State == PSInvocationState.Completed) { // Special case for failure error due to ErrorCode==-2144108453 (no ShellId found). // In this case terminate session since there is no longer a shell to communicate // with. bool terminateSession = false; if (stateInfo.State == PSInvocationState.Failed) { PSRemotingTransportException remotingTransportException = stateInfo.Reason as PSRemotingTransportException; terminateSession = (remotingTransportException != null) && (remotingTransportException.ErrorCode == System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_TARGETSESSION_DOESNOTEXIST); } // if state is completed or failed or stopped, // then the collections need to be closed as // well, else the enumerator will block UnblockCollections(); if (stopCalled || terminateSession) { // Reset stop called flag. stopCalled = false; // if a Stop method has been called, then powershell // would have already raised a Stopping event, after // which only a Stopped should be raised _stateInfoQueue.Enqueue(new PSInvocationStateInfo(PSInvocationState.Stopped, stateInfo.Reason)); // If the stop call failed due to network problems then close the runspace // since it is now unusable. CheckAndCloseRunspaceAfterStop(stateInfo.Reason); } else { _stateInfoQueue.Enqueue(stateInfo); } // calling close async only after making sure all the internal members are prepared // to handle close complete. dataStructureHandler.CloseConnectionAsync(null); } } }
internal void HandleTransportError(object sender, TransportErrorOccuredEventArgs e) { PSInvocationStateInfo data = new PSInvocationStateInfo(PSInvocationState.Failed, e.Exception); this.InvocationStateInfoReceived.SafeInvoke <RemoteDataEventArgs <PSInvocationStateInfo> >(this, new RemoteDataEventArgs <PSInvocationStateInfo>(data)); }
internal void ProcessReceivedData(RemoteDataObject <PSObject> receivedData) { if (receivedData.PowerShellId != this.clientPowerShellId) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.PipelineIdsDoNotMatch, new object[] { receivedData.PowerShellId, this.clientPowerShellId }); } switch (receivedData.DataType) { case RemotingDataType.PowerShellOutput: { object powerShellOutput = RemotingDecoder.GetPowerShellOutput(receivedData.Data); this.OutputReceived.SafeInvoke <RemoteDataEventArgs <object> >(this, new RemoteDataEventArgs <object>(powerShellOutput)); return; } case RemotingDataType.PowerShellErrorRecord: { ErrorRecord powerShellError = RemotingDecoder.GetPowerShellError(receivedData.Data); this.ErrorReceived.SafeInvoke <RemoteDataEventArgs <ErrorRecord> >(this, new RemoteDataEventArgs <ErrorRecord>(powerShellError)); return; } case RemotingDataType.PowerShellStateInfo: { PSInvocationStateInfo powerShellStateInfo = RemotingDecoder.GetPowerShellStateInfo(receivedData.Data); this.InvocationStateInfoReceived.SafeInvoke <RemoteDataEventArgs <PSInvocationStateInfo> >(this, new RemoteDataEventArgs <PSInvocationStateInfo>(powerShellStateInfo)); return; } case RemotingDataType.PowerShellDebug: { DebugRecord powerShellDebug = RemotingDecoder.GetPowerShellDebug(receivedData.Data); this.InformationalMessageReceived.SafeInvoke <RemoteDataEventArgs <InformationalMessage> >(this, new RemoteDataEventArgs <InformationalMessage>(new InformationalMessage(powerShellDebug, RemotingDataType.PowerShellDebug))); return; } case RemotingDataType.PowerShellVerbose: { VerboseRecord powerShellVerbose = RemotingDecoder.GetPowerShellVerbose(receivedData.Data); this.InformationalMessageReceived.SafeInvoke <RemoteDataEventArgs <InformationalMessage> >(this, new RemoteDataEventArgs <InformationalMessage>(new InformationalMessage(powerShellVerbose, RemotingDataType.PowerShellVerbose))); return; } case RemotingDataType.PowerShellWarning: { WarningRecord powerShellWarning = RemotingDecoder.GetPowerShellWarning(receivedData.Data); this.InformationalMessageReceived.SafeInvoke <RemoteDataEventArgs <InformationalMessage> >(this, new RemoteDataEventArgs <InformationalMessage>(new InformationalMessage(powerShellWarning, RemotingDataType.PowerShellWarning))); return; } case ((RemotingDataType)0x4100a): case ((RemotingDataType)0x4100b): case ((RemotingDataType)0x4100c): case ((RemotingDataType)0x4100d): case ((RemotingDataType)0x4100e): case ((RemotingDataType)0x4100f): break; case RemotingDataType.PowerShellProgress: { ProgressRecord powerShellProgress = RemotingDecoder.GetPowerShellProgress(receivedData.Data); this.InformationalMessageReceived.SafeInvoke <RemoteDataEventArgs <InformationalMessage> >(this, new RemoteDataEventArgs <InformationalMessage>(new InformationalMessage(powerShellProgress, RemotingDataType.PowerShellProgress))); return; } case RemotingDataType.RemoteHostCallUsingPowerShellHost: { RemoteHostCall data = RemoteHostCall.Decode(receivedData.Data); this.HostCallReceived.SafeInvoke <RemoteDataEventArgs <RemoteHostCall> >(this, new RemoteDataEventArgs <RemoteHostCall>(data)); break; } default: return; } }
/// <summary> /// Set the state information of the client powershell /// </summary> /// <param name="stateInfo">state information to set</param> internal void SetStateInfo(PSInvocationStateInfo stateInfo) { shell.SetStateChanged(stateInfo); }
internal PSInvocationStateChangedEventArgs(PSInvocationStateInfo psStateInfo) { using (PSInvocationStateChangedEventArgs.tracer.TraceConstructor((object)this)) this.executionStateInfo = psStateInfo; }
internal void SetStateInfo(PSInvocationStateInfo stateInfo) { using (ClientRemotePowerShell.tracer.TraceMethod()) this.shell.SetStateChanged(stateInfo); }