private void HandleCreateAndInvokePowerShell(object sender, RemoteDataEventArgs <RemoteDataObject <PSObject> > eventArgs) { RemoteDataObject <PSObject> data = eventArgs.Data; HostInfo hostInfo = RemotingDecoder.GetHostInfo(data.Data); ApartmentState apartmentState = RemotingDecoder.GetApartmentState(data.Data); RemoteStreamOptions remoteStreamOptions = RemotingDecoder.GetRemoteStreamOptions(data.Data); PowerShell powerShell = RemotingDecoder.GetPowerShell(data.Data); bool noInput = RemotingDecoder.GetNoInput(data.Data); bool addToHistory = RemotingDecoder.GetAddToHistory(data.Data); bool isNested = false; if (this.serverCapability.ProtocolVersion >= RemotingConstants.ProtocolVersionWin8RTM) { isNested = RemotingDecoder.GetIsNested(data.Data); } if (isNested) { if (this.dsHandler.GetAssociatedPowerShellDataStructureHandler(powerShell.InstanceId) != null) { throw new InvalidOperationException("NestedPipeline is not supported in this release."); } powerShell.SetIsNested(false); if ((this.localRunspacePool.GetMaxRunspaces() == 1) && (this.dsHandler.GetPowerShellDataStructureHandler() != null)) { new ServerSteppablePipelineDriver(powerShell, noInput, data.PowerShellId, data.RunspacePoolId, this, apartmentState, hostInfo, remoteStreamOptions, addToHistory, this.rsToUseForSteppablePipeline, this.eventSubscriber, this.inputCollection).Start(); return; } } ServerPowerShellDriver driver2 = new ServerPowerShellDriver(powerShell, null, noInput, data.PowerShellId, data.RunspacePoolId, this, apartmentState, hostInfo, remoteStreamOptions, addToHistory, null); this.inputCollection = driver2.InputCollection; driver2.Start(); }
/// <summary> /// Constructs a remote pipeline for the specified runspace and /// specified command. /// </summary> /// <param name="runspace">Runspace in which to create the pipeline.</param> /// <param name="command">Command as a string, to be used in pipeline creation.</param> /// <param name="addToHistory">Whether to add the command to the runspaces history.</param> /// <param name="isNested">Whether this pipeline is nested.</param> internal RemotePipeline(RemoteRunspace runspace, string command, bool addToHistory, bool isNested) : this(runspace, addToHistory, isNested) { if (command != null) { _commands.Add(new Command(command, true)); } // initialize the underlying powershell object _powershell = new PowerShell(_inputStream, _outputStream, _errorStream, ((RemoteRunspace)_runspace).RunspacePool); _powershell.SetIsNested(isNested); _powershell.InvocationStateChanged += HandleInvocationStateChanged; }
/// <summary> /// Helper method to invoke a PSCommand on a given runspace. This method correctly invokes the command for /// these runspace cases: /// 1. Local runspace. If the local runspace is busy it will invoke as a nested command. /// 2. Remote runspace. /// 3. Runspace that is stopped in the debugger at a breakpoint. /// /// Error and information streams are ignored and only the command result output is returned. /// /// This method is NOT thread safe. It does not support running commands from different threads on the /// provided runspace. It assumes the thread invoking this method is the same that runs all other /// commands on the provided runspace. /// </summary> /// <param name="runspace">Runspace to invoke the command on.</param> /// <param name="command">Command to invoke.</param> /// <returns>Collection of command output result objects.</returns> public static Collection <PSObject> InvokeOnRunspace(PSCommand command, Runspace runspace) { if (command == null) { throw new PSArgumentNullException("command"); } if (runspace == null) { throw new PSArgumentNullException("runspace"); } if ((runspace.Debugger != null) && runspace.Debugger.InBreakpoint) { // Use the Debugger API to run the command when a runspace is stopped in the debugger. PSDataCollection <PSObject> output = new PSDataCollection <PSObject>(); runspace.Debugger.ProcessCommand( command, output); return(new Collection <PSObject>(output)); } // Otherwise run command directly in runspace. PowerShell ps = PowerShell.Create(); ps.Runspace = runspace; ps.IsRunspaceOwner = false; if (runspace.ConnectionInfo == null) { // Local runspace. Make a nested PowerShell object as needed. ps.SetIsNested(runspace.GetCurrentlyRunningPipeline() != null); } using (ps) { ps.Commands = command; return(ps.Invoke <PSObject>()); } }
/// <summary> /// internal method to set the value of IsNested. This is called /// by serializer /// </summary> internal void SetIsNested(bool isNested) { _isNested = isNested; _powershell.SetIsNested(isNested); }