internal static void Dispatch(
            BaseClientTransportManager transportManager,
            PSHost clientHost,
            PSDataCollectionStream <ErrorRecord> errorStream,
            ObjectStream methodExecutorStream,
            bool isMethodExecutorStreamEnabled,
            RemoteRunspacePoolInternal runspacePool,
            Guid clientPowerShellId,
            RemoteHostCall remoteHostCall)
        {
            ClientMethodExecutor clientMethodExecutor = new ClientMethodExecutor(transportManager, clientHost, runspacePool.InstanceId, clientPowerShellId, remoteHostCall);

            if (clientPowerShellId == Guid.Empty)
            {
                clientMethodExecutor.Execute(errorStream);
            }
            else if (remoteHostCall.IsSetShouldExit && isMethodExecutorStreamEnabled)
            {
                runspacePool.Close();
            }
            else if (isMethodExecutorStreamEnabled)
            {
                methodExecutorStream.Write((object)clientMethodExecutor);
            }
            else
            {
                clientMethodExecutor.Execute(errorStream);
            }
        }
        /// <summary>
        /// Execute method.
        /// </summary>
        internal T ExecuteMethod <T>(RemoteHostMethodId methodId, object[] parameters)
        {
            Dbg.Assert(parameters != null, "Expected parameters != null");

            // Create the method call object.
            long           callId         = _serverDispatchTable.CreateNewCallId();
            RemoteHostCall remoteHostCall = new RemoteHostCall(callId, methodId, parameters);

            RemoteDataObject <PSObject> dataToBeSent = RemoteDataObject <PSObject> .CreateFrom(RemotingDestination.Client,
                                                                                               _remoteHostCallDataType, _clientRunspacePoolId, _clientPowerShellId,
                                                                                               remoteHostCall.Encode());

            // report that execution is pending host response
            _transportManager.SendDataToClient(dataToBeSent, false, true);

            // Wait for response.
            RemoteHostResponse remoteHostResponse = _serverDispatchTable.GetResponse(callId, null);

            // Null means that the response PSObject was not received and there was an error.
            if (remoteHostResponse == null)
            {
                throw RemoteHostExceptions.NewRemoteHostCallFailedException(methodId);
            }

            // Process the response.
            object returnValue = remoteHostResponse.SimulateExecution();

            Dbg.Assert(returnValue is T, "Expected returnValue is T");
            return((T)remoteHostResponse.SimulateExecution());
        }
        /// <summary>
        /// Create a new ClientMethodExecutor object and then dispatch it.
        /// </summary>
        internal static void Dispatch(
            BaseClientTransportManager transportManager,
            PSHost clientHost,
            PSDataCollectionStream <ErrorRecord> errorStream,
            ObjectStream methodExecutorStream,
            bool isMethodExecutorStreamEnabled,
            RemoteRunspacePoolInternal runspacePool,
            Guid clientPowerShellId,
            RemoteHostCall remoteHostCall)
        {
            ClientMethodExecutor methodExecutor =
                new ClientMethodExecutor(transportManager, clientHost, runspacePool.InstanceId,
                                         clientPowerShellId, remoteHostCall);

            // If the powershell id is not specified, this message is for the runspace pool, execute
            // it immediately and return
            if (clientPowerShellId == Guid.Empty)
            {
                methodExecutor.Execute(errorStream);
                return;
            }

            // Check client host to see if SetShouldExit should be allowed
            bool hostAllowSetShouldExit = false;

            if (clientHost != null)
            {
                PSObject hostPrivateData = clientHost.PrivateData as PSObject;
                if (hostPrivateData != null)
                {
                    PSNoteProperty allowSetShouldExit = hostPrivateData.Properties["AllowSetShouldExitFromRemote"] as PSNoteProperty;
                    hostAllowSetShouldExit = allowSetShouldExit != null && allowSetShouldExit.Value is bool && (bool)allowSetShouldExit.Value;
                }
            }

            // Should we kill remote runspace? Check if "SetShouldExit" and if we are in the
            // cmdlet case. In the API case (when we are invoked from an API not a cmdlet) we
            // should not interpret "SetShouldExit" but should pass it on to the host. The
            // variable IsMethodExecutorStreamEnabled is only true in the cmdlet case. In the
            // API case it is false.

            if (remoteHostCall.IsSetShouldExit && isMethodExecutorStreamEnabled && !hostAllowSetShouldExit)
            {
                runspacePool.Close();
                return;
            }

            // Cmdlet case: queue up the executor in the pipeline stream.
            if (isMethodExecutorStreamEnabled)
            {
                Dbg.Assert(methodExecutorStream != null, "method executor stream can't be null when enabled");
                methodExecutorStream.Write(methodExecutor);
            }

            // API case: execute it immediately.
            else
            {
                methodExecutor.Execute(errorStream);
            }
        }
Exemple #4
0
 /// <summary>
 /// Constructor for ClientMethodExecutor.
 /// </summary>
 private ClientMethodExecutor(BaseClientTransportManager transportManager, PSHost clientHost, Guid clientRunspacePoolId, Guid clientPowerShellId, RemoteHostCall remoteHostCall)
 {
     Dbg.Assert(transportManager != null, "Expected transportManager != null");
     Dbg.Assert(remoteHostCall != null, "Expected remoteHostCall != null");
     _transportManager     = transportManager;
     _remoteHostCall       = remoteHostCall;
     _clientHost           = clientHost;
     _clientRunspacePoolId = clientRunspacePoolId;
     _clientPowerShellId   = clientPowerShellId;
 }
 /// <summary>
 /// Constructor for ClientMethodExecutor.
 /// </summary>
 private ClientMethodExecutor(BaseClientTransportManager transportManager, PSHost clientHost, Guid clientRunspacePoolId, Guid clientPowerShellId, RemoteHostCall remoteHostCall)
 {
     Dbg.Assert(transportManager != null, "Expected transportManager != null");
     Dbg.Assert(remoteHostCall != null, "Expected remoteHostCall != null");
     _transportManager = transportManager;
     _remoteHostCall = remoteHostCall;
     _clientHost = clientHost;
     _clientRunspacePoolId = clientRunspacePoolId;
     _clientPowerShellId = clientPowerShellId;
 }
Exemple #6
0
        internal static RemoteHostCall Decode(PSObject data)
        {
            long                 propertyValue1       = RemotingDecoder.GetPropertyValue <long>(data, "ci");
            PSObject             propertyValue2       = RemotingDecoder.GetPropertyValue <PSObject>(data, "mp");
            RemoteHostMethodId   propertyValue3       = RemotingDecoder.GetPropertyValue <RemoteHostMethodId>(data, "mi");
            RemoteHostMethodInfo remoteHostMethodInfo = RemoteHostMethodInfo.LookUp(propertyValue3);

            object[] parameters = RemoteHostCall.DecodeParameters(propertyValue2, remoteHostMethodInfo.ParameterTypes);
            return(new RemoteHostCall(propertyValue1, propertyValue3, parameters));
        }
Exemple #7
0
        internal PSObject Encode()
        {
            PSObject emptyPsObject = RemotingEncoder.CreateEmptyPSObject();
            PSObject psObject      = RemoteHostCall.EncodeParameters(this._parameters);

            emptyPsObject.Properties.Add((PSPropertyInfo) new PSNoteProperty("ci", (object)this._callId));
            emptyPsObject.Properties.Add((PSPropertyInfo) new PSNoteProperty("mi", (object)this._methodId));
            emptyPsObject.Properties.Add((PSPropertyInfo) new PSNoteProperty("mp", (object)psObject));
            return(emptyPsObject);
        }
 private ClientMethodExecutor(
     BaseClientTransportManager transportManager,
     PSHost clientHost,
     Guid clientRunspacePoolId,
     Guid clientPowerShellId,
     RemoteHostCall remoteHostCall)
 {
     this._transportManager     = transportManager;
     this._remoteHostCall       = remoteHostCall;
     this._clientHost           = clientHost;
     this._clientRunspacePoolId = clientRunspacePoolId;
     this._clientPowerShellId   = clientPowerShellId;
 }
        /// <summary>
        /// Execute void method.
        /// </summary>
        internal void ExecuteVoidMethod(RemoteHostMethodId methodId, object[] parameters)
        {
            Dbg.Assert(parameters != null, "Expected parameters != null");

            // Use void call ID so that the call is known to not have a return value.
            long callId = ServerDispatchTable.VoidCallId;
            RemoteHostCall remoteHostCall = new RemoteHostCall(callId, methodId, parameters);

            // Dispatch the call but don't wait for response since the return value is void.

            // TODO: remove redundant data from the RemoteHostCallPacket.
            RemoteDataObject<PSObject> dataToBeSent = RemoteDataObject<PSObject>.CreateFrom(RemotingDestination.Client,
                _remoteHostCallDataType, _clientRunspacePoolId, _clientPowerShellId,
                remoteHostCall.Encode());
            // flush is not used here..since this is a void method and server host
            // does not expect anything from client..so let the transport manager buffer
            // and send as much data as possible.
            _transportManager.SendDataToClient(dataToBeSent, false);
        }
        /// <summary>
        /// Decode object.
        /// </summary>
        internal static object DecodeObject(object obj, Type type)
        {
            if (obj == null)
            {
                return(null);
            }

            Dbg.Assert(type != null, "Expected type != null");
            if (type == typeof(PSObject))
            {
                return(DecodePSObject(obj));
            }
            else if (type == typeof(ProgressRecord))
            {
                return(ProgressRecord.FromPSObjectForRemoting(PSObject.AsPSObject(obj)));
            }
            else if (IsKnownType(type))
            {
                return(obj);
            }
            else if (obj is SecureString)
            {
                return(obj);
            }
            else if (obj is PSCredential)
            {
                return(obj);
            }
            else if (obj is PSObject && type == typeof(PSCredential))
            {
                // BUGBUG: The following piece of code is a workaround
                // because custom serialization is busted. If rehydration
                // works correctly then PSCredential should be available
                PSObject     objAsPSObject = (PSObject)obj;
                PSCredential cred          = null;
                try
                {
                    cred = new PSCredential((string)objAsPSObject.Properties["UserName"].Value,
                                            (SecureString)objAsPSObject.Properties["Password"].Value);
                }
                catch (GetValueException)
                {
                    cred = null;
                }

                return(cred);
            }
            else if (obj is int && type.IsEnum)
            {
                return(Enum.ToObject(type, (int)obj));
            }
            else if (obj is string && type == typeof(CultureInfo))
            {
                return(new CultureInfo((string)obj));
            }
            else if (obj is PSObject && type == typeof(Exception))
            {
                return(DecodeException((PSObject)obj));
            }
            else if (obj is PSObject && type == typeof(object[]))
            {
                return(DecodeObjectArray((PSObject)obj));
            }
            else if (obj is PSObject && type.IsArray)
            {
                return(DecodeArray((PSObject)obj, type));
            }
            else if (obj is PSObject && IsCollection(type))
            {
                return(DecodeCollection((PSObject)obj, type));
            }
            else if (obj is PSObject && IsDictionary(type))
            {
                return(DecodeDictionary((PSObject)obj, type));
            }
            else if (obj is PSObject && IsEncodingAllowedForClassOrStruct(type))
            {
                return(DecodeClassOrStruct((PSObject)obj, type));
            }
            else if (obj is PSObject && IsGenericIEnumerableOfInt(type))
            {
                // we cannot create an instance of interface type like IEnumerable
                // Since a Collection implements IEnumerable, falling back to use
                // that.
                return(DecodeCollection((PSObject)obj, typeof(Collection <int>)));
            }
            else if (obj is PSObject && type == typeof(RemoteHostCall))
            {
                return(RemoteHostCall.Decode((PSObject)obj));
            }
            else if (obj is PSObject && type == typeof(RemoteHostResponse))
            {
                return(RemoteHostResponse.Decode((PSObject)obj));
            }
            else
            {
                throw RemoteHostExceptions.NewRemoteHostDataDecodingNotSupportedException(type);
            }
        }
        /// <summary>
        /// Handles a robust connection layer notification from the transport
        /// manager.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleRobustConnectionNotification(
            object sender,
            ConnectionStatusEventArgs e)
        {
            // Create event arguments and warnings/errors for this robust connection notification.
            PSConnectionRetryStatusEventArgs connectionRetryStatusArgs = null;
            WarningRecord warningRecord = null;
            ErrorRecord errorRecord = null;
            int maxRetryConnectionTimeMSecs = this.runspacePool.MaxRetryConnectionTime;
            int maxRetryConnectionTimeMinutes = maxRetryConnectionTimeMSecs / 60000;
            switch (e.Notification)
            {
                case ConnectionStatus.NetworkFailureDetected:
                    warningRecord = new WarningRecord(
                        PSConnectionRetryStatusEventArgs.FQIDNetworkFailureDetected,
                        StringUtil.Format(RemotingErrorIdStrings.RCNetworkFailureDetected,
                        this.computerName, maxRetryConnectionTimeMinutes));

                    connectionRetryStatusArgs =
                        new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.NetworkFailureDetected,
                            this.computerName, maxRetryConnectionTimeMSecs, warningRecord);
                    break;

                case ConnectionStatus.ConnectionRetryAttempt:
                    warningRecord = new WarningRecord(
                        PSConnectionRetryStatusEventArgs.FQIDConnectionRetryAttempt,
                        StringUtil.Format(RemotingErrorIdStrings.RCConnectionRetryAttempt, this.computerName));

                    connectionRetryStatusArgs =
                        new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.ConnectionRetryAttempt,
                            this.computerName, maxRetryConnectionTimeMSecs, warningRecord);
                    break;

                case ConnectionStatus.ConnectionRetrySucceeded:
                    warningRecord = new WarningRecord(
                        PSConnectionRetryStatusEventArgs.FQIDConnectionRetrySucceeded,
                        StringUtil.Format(RemotingErrorIdStrings.RCReconnectSucceeded, this.computerName));

                    connectionRetryStatusArgs =
                        new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.ConnectionRetrySucceeded,
                            this.computerName, maxRetryConnectionTimeMinutes, warningRecord);
                    break;

                case ConnectionStatus.AutoDisconnectStarting:
                    {
                        warningRecord = new WarningRecord(
                            PSConnectionRetryStatusEventArgs.FQIDAutoDisconnectStarting,
                            StringUtil.Format(RemotingErrorIdStrings.RCAutoDisconnectingWarning, this.computerName));

                        connectionRetryStatusArgs =
                            new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.AutoDisconnectStarting,
                                this.computerName, maxRetryConnectionTimeMinutes, warningRecord);
                    }
                    break;

                case ConnectionStatus.AutoDisconnectSucceeded:
                    warningRecord = new WarningRecord(
                        PSConnectionRetryStatusEventArgs.FQIDAutoDisconnectSucceeded,
                        StringUtil.Format(RemotingErrorIdStrings.RCAutoDisconnected, this.computerName));

                    connectionRetryStatusArgs =
                        new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.AutoDisconnectSucceeded,
                            this.computerName, maxRetryConnectionTimeMinutes, warningRecord);
                    break;

                case ConnectionStatus.InternalErrorAbort:
                    {
                        string msg = StringUtil.Format(RemotingErrorIdStrings.RCInternalError, this.computerName);
                        RuntimeException reason = new RuntimeException(msg);
                        errorRecord = new ErrorRecord(reason,
                            PSConnectionRetryStatusEventArgs.FQIDNetworkOrDisconnectFailed,
                            ErrorCategory.InvalidOperation, this);

                        connectionRetryStatusArgs =
                            new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.InternalErrorAbort,
                                this.computerName, maxRetryConnectionTimeMinutes, errorRecord);
                    }
                    break;
            }

            if (connectionRetryStatusArgs == null)
            {
                return;
            }

            // Update connection status.
            _connectionRetryStatus = connectionRetryStatusArgs.Notification;

            if (warningRecord != null)
            {
                RemotingWarningRecord remotingWarningRecord = new RemotingWarningRecord(
                    warningRecord,
                    new OriginInfo(this.computerName, this.InstanceId));

                // Add warning record to information channel.
                HandleInformationalMessageReceived(this,
                    new RemoteDataEventArgs<InformationalMessage>(
                        new InformationalMessage(remotingWarningRecord, RemotingDataType.PowerShellWarning)));

                // Write warning to host.
                RemoteHostCall writeWarning = new RemoteHostCall(
                    -100,
                    RemoteHostMethodId.WriteWarningLine,
                    new object[] { warningRecord.Message });

                try
                {
                    HandleHostCallReceived(this,
                        new RemoteDataEventArgs<RemoteHostCall>(writeWarning));
                }
                catch (PSNotImplementedException)
                { }
            }

            if (errorRecord != null)
            {
                RemotingErrorRecord remotingErrorRecord = new RemotingErrorRecord(
                    errorRecord,
                    new OriginInfo(this.computerName, this.InstanceId));

                // Add error record to error channel, will also be written to host.
                HandleErrorReceived(this,
                    new RemoteDataEventArgs<ErrorRecord>(remotingErrorRecord));
            }

            // Raise event.
            RCConnectionNotification.SafeInvoke(this, connectionRetryStatusArgs);
        }
        /// <summary>
        /// Execute the specified host call
        /// </summary>
        /// <param name="hostcall">host call to execute</param>
        private void ExecuteHostCall(RemoteHostCall hostcall)
        {
            if (hostcall.IsVoidMethod)
            {
                if (hostcall.IsSetShouldExitOrPopRunspace)
                {
                    this.shell.ClearRemotePowerShell();
                }

                hostcall.ExecuteVoidMethod(hostToUse);
            }
            else
            {
                RemoteHostResponse remoteHostResponse = hostcall.ExecuteNonVoidMethod(hostToUse);
                dataStructureHandler.SendHostResponseToServer(remoteHostResponse);
            }
        }
Exemple #13
0
 internal static object DecodeObject(object obj, Type type)
 {
     if (obj == null)
     {
         return(obj);
     }
     if (type == typeof(PSObject))
     {
         return(DecodePSObject(obj));
     }
     if (type == typeof(System.Management.Automation.Runspaces.Runspace))
     {
         return(RemoteRunspace.FromPSObjectForRemoting(PSObject.AsPSObject(obj)));
     }
     if (type == typeof(ProgressRecord))
     {
         return(ProgressRecord.FromPSObjectForRemoting(PSObject.AsPSObject(obj)));
     }
     if (IsKnownType(type))
     {
         return(obj);
     }
     if (obj is SecureString)
     {
         return(obj);
     }
     if (obj is PSCredential)
     {
         return(obj);
     }
     if ((obj is PSObject) && (type == typeof(PSCredential)))
     {
         PSObject obj2 = (PSObject)obj;
         try
         {
             return(new PSCredential((string)obj2.Properties["UserName"].Value, (SecureString)obj2.Properties["Password"].Value));
         }
         catch (GetValueException)
         {
             return(null);
         }
     }
     if ((obj is int) && type.IsEnum)
     {
         return(Enum.ToObject(type, (int)obj));
     }
     if ((obj is string) && (type == typeof(CultureInfo)))
     {
         return(new CultureInfo((string)obj));
     }
     if ((obj is PSObject) && (type == typeof(Exception)))
     {
         return(DecodeException((PSObject)obj));
     }
     if ((obj is PSObject) && (type == typeof(object[])))
     {
         return(DecodeObjectArray((PSObject)obj));
     }
     if ((obj is PSObject) && type.IsArray)
     {
         return(DecodeArray((PSObject)obj, type));
     }
     if ((obj is PSObject) && IsCollection(type))
     {
         return(DecodeCollection((PSObject)obj, type));
     }
     if ((obj is PSObject) && IsDictionary(type))
     {
         return(DecodeDictionary((PSObject)obj, type));
     }
     if ((obj is PSObject) && IsEncodingAllowedForClassOrStruct(type))
     {
         return(DecodeClassOrStruct((PSObject)obj, type));
     }
     if ((obj is PSObject) && IsGenericIEnumerableOfInt(type))
     {
         return(DecodeCollection((PSObject)obj, typeof(Collection <int>)));
     }
     if ((obj is PSObject) && (type == typeof(RemoteHostCall)))
     {
         return(RemoteHostCall.Decode((PSObject)obj));
     }
     if (!(obj is PSObject) || (type != typeof(RemoteHostResponse)))
     {
         throw RemoteHostExceptions.NewRemoteHostDataDecodingNotSupportedException(type);
     }
     return(RemoteHostResponse.Decode((PSObject)obj));
 }
        private void HandleRobustConnectionNotification(object sender, ConnectionStatusEventArgs e)
        {
            PSConnectionRetryStatusEventArgs eventArgs = null;
            WarningRecord infoRecord = null;
            ErrorRecord record2 = null;
            int maxRetryConnectionTime = this.runspacePool.MaxRetryConnectionTime;
            int num2 = maxRetryConnectionTime / 0xea60;
            switch (e.Notification)
            {
                case ConnectionStatus.NetworkFailureDetected:
                    infoRecord = new WarningRecord("PowerShellNetworkFailureDetected", StringUtil.Format(RemotingErrorIdStrings.RCNetworkFailureDetected, this.computerName, num2));
                    eventArgs = new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.NetworkFailureDetected, this.computerName, maxRetryConnectionTime, infoRecord);
                    break;

                case ConnectionStatus.ConnectionRetryAttempt:
                    infoRecord = new WarningRecord("PowerShellConnectionRetryAttempt", StringUtil.Format(RemotingErrorIdStrings.RCConnectionRetryAttempt, this.computerName));
                    eventArgs = new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.ConnectionRetryAttempt, this.computerName, maxRetryConnectionTime, infoRecord);
                    break;

                case ConnectionStatus.ConnectionRetrySucceeded:
                    infoRecord = new WarningRecord("PowerShellConnectionRetrySucceeded", StringUtil.Format(RemotingErrorIdStrings.RCReconnectSucceeded, this.computerName));
                    eventArgs = new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.ConnectionRetrySucceeded, this.computerName, num2, infoRecord);
                    break;

                case ConnectionStatus.AutoDisconnectStarting:
                    infoRecord = new WarningRecord("PowerShellNetworkFailedStartDisconnect", StringUtil.Format(RemotingErrorIdStrings.RCAutoDisconnectingWarning, this.computerName));
                    eventArgs = new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.AutoDisconnectStarting, this.computerName, num2, infoRecord);
                    break;

                case ConnectionStatus.AutoDisconnectSucceeded:
                    infoRecord = new WarningRecord("PowerShellAutoDisconnectSucceeded", StringUtil.Format(RemotingErrorIdStrings.RCAutoDisconnected, this.computerName));
                    eventArgs = new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.AutoDisconnectSucceeded, this.computerName, num2, infoRecord);
                    break;

                case ConnectionStatus.InternalErrorAbort:
                {
                    RuntimeException exception = new RuntimeException(StringUtil.Format(RemotingErrorIdStrings.RCInternalError, this.computerName));
                    record2 = new ErrorRecord(exception, "PowerShellNetworkOrDisconnectFailed", ErrorCategory.InvalidOperation, this);
                    eventArgs = new PSConnectionRetryStatusEventArgs(PSConnectionRetryStatus.InternalErrorAbort, this.computerName, num2, record2);
                    break;
                }
            }
            if (eventArgs != null)
            {
                this.connectionRetryStatus = eventArgs.Notification;
                if (infoRecord != null)
                {
                    RemotingWarningRecord message = new RemotingWarningRecord(infoRecord, new OriginInfo(this.computerName, this.InstanceId));
                    this.HandleInformationalMessageReceived(this, new RemoteDataEventArgs<InformationalMessage>(new InformationalMessage(message, RemotingDataType.PowerShellWarning)));
                    RemoteHostCall data = new RemoteHostCall(-100L, RemoteHostMethodId.WriteWarningLine, new object[] { infoRecord.Message });
                    try
                    {
                        this.HandleHostCallReceived(this, new RemoteDataEventArgs<RemoteHostCall>(data));
                    }
                    catch (PSNotImplementedException)
                    {
                    }
                }
                if (record2 != null)
                {
                    RemotingErrorRecord record4 = new RemotingErrorRecord(record2, new OriginInfo(this.computerName, this.InstanceId));
                    this.HandleErrorReceived(this, new RemoteDataEventArgs<ErrorRecord>(record4));
                }
                this.RCConnectionNotification.SafeInvoke<PSConnectionRetryStatusEventArgs>(this, eventArgs);
            }
        }
        /// <summary>
        /// Create a new ClientMethodExecutor object and then dispatch it.
        /// </summary>
        internal static void Dispatch(
            BaseClientTransportManager transportManager,
            PSHost clientHost,
            PSDataCollectionStream<ErrorRecord> errorStream,
            ObjectStream methodExecutorStream,
            bool isMethodExecutorStreamEnabled,
            RemoteRunspacePoolInternal runspacePool,
            Guid clientPowerShellId,
            RemoteHostCall remoteHostCall)
        {
            ClientMethodExecutor methodExecutor =
                new ClientMethodExecutor(transportManager, clientHost, runspacePool.InstanceId,
                    clientPowerShellId, remoteHostCall);

            // If the powershell id is not specified, this message is for the runspace pool, execute
            // it immediately and return
            if (clientPowerShellId == Guid.Empty)
            {
                methodExecutor.Execute(errorStream);
                return;
            }

            // Check client host to see if SetShouldExit should be allowed
            bool hostAllowSetShouldExit = false;
            if (clientHost != null)
            {
                PSObject hostPrivateData = clientHost.PrivateData as PSObject;
                if (hostPrivateData != null)
                {
                    PSNoteProperty allowSetShouldExit = hostPrivateData.Properties["AllowSetShouldExitFromRemote"] as PSNoteProperty;
                    hostAllowSetShouldExit = (allowSetShouldExit != null && allowSetShouldExit.Value is bool) ?
                        (bool)allowSetShouldExit.Value : false;
                }
            }

            // Should we kill remote runspace? Check if "SetShouldExit" and if we are in the
            // cmdlet case. In the API case (when we are invoked from an API not a cmdlet) we
            // should not interpret "SetShouldExit" but should pass it on to the host. The
            // variable IsMethodExecutorStreamEnabled is only true in the cmdlet case. In the
            // API case it is false.

            if (remoteHostCall.IsSetShouldExit && isMethodExecutorStreamEnabled && !hostAllowSetShouldExit)
            {
                runspacePool.Close();
                return;
            }

            // Cmdlet case: queue up the executor in the pipeline stream.
            if (isMethodExecutorStreamEnabled)
            {
                Dbg.Assert(!isMethodExecutorStreamEnabled ||
                           (isMethodExecutorStreamEnabled && methodExecutorStream != null),
                           "method executor stream can't be null when enabled");
                methodExecutorStream.Write(methodExecutor);
            }

            // API case: execute it immediately.
            else
            {
                methodExecutor.Execute(errorStream);
            }
        }