diff --git a/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs b/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs index 4703cd1c871..87135c2e2bf 100644 --- a/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs @@ -39,6 +39,7 @@ public class EnterPSSessionCommand : PSRemotingBaseCmdlet /// public new Int32 ThrottleLimit { set { } get { return 0; } } private ObjectStream _stream; + private RemoteRunspace _tempRunspace; #endregion @@ -533,7 +534,18 @@ protected override void EndProcessing() /// /// protected override void StopProcessing() - { + { + var remoteRunspace = _tempRunspace; + if (remoteRunspace != null) + { + try + { + remoteRunspace.CloseAsync(); + } + catch (InvalidRunspaceStateException) { } + return; + } + IHostSupportsInteractiveSession host = this.Host as IHostSupportsInteractiveSession; if (host == null) { @@ -1272,10 +1284,16 @@ private RemoteRunspace GetRunspaceForSSHSession() { var sshConnectionInfo = new SSHConnectionInfo(this.UserName, ResolveComputerName(HostName), this.KeyFilePath, this.Port); var typeTable = TypeTable.LoadDefaultTypeFiles(); - var remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace; - remoteRunspace.Open(); - remoteRunspace.ShouldCloseOnPop = true; + // Use the class _tempRunspace field while the runspace is being opened so that StopProcessing can be handled at that time. + // This is only needed for SSH sessions where a Ctrl+C during an SSH password prompt can abort the session before a connection + // is established. + _tempRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace; + _tempRunspace.Open(); + _tempRunspace.ShouldCloseOnPop = true; + var remoteRunspace = _tempRunspace; + _tempRunspace = null; + return remoteRunspace; } diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs index d665c6d77a9..916ae466498 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs @@ -1403,6 +1403,7 @@ internal sealed class SSHClientSessionTransportManager : OutOfProcessClientSessi private StreamWriter _stdInWriter; private StreamReader _stdOutReader; private StreamReader _stdErrReader; + private bool _connectionEstablished; private const string _threadName = "SSHTransport Reader Thread"; #endregion @@ -1464,7 +1465,12 @@ internal override void CreateAsync() internal override void CloseAsync() { base.CloseAsync(); - CloseConnection(); + + if (!_connectionEstablished) + { + // If the connection is not yet estalished then clean up any existing connection state. + CloseConnection(); + } } #endregion @@ -1641,6 +1647,9 @@ private void ProcessReaderThread(object state) } else { + // The first received PSRP message from the server indicates that the connection is established and that PSRP is running. + if (!_connectionEstablished) { _connectionEstablished = true; } + // Normal output data. HandleOutputDataReceived(data); } @@ -2410,3 +2419,4 @@ internal override void Close(Exception reasonForClose) #endregion } } +