/// <summary> /// Called once before ProcessRecord(). Internally it calls /// BeginProcessing() of the InternalCommand. /// </summary> /// <exception cref="PipelineStoppedException"> /// a terminating error occurred, or the pipeline was otherwise stopped /// </exception> internal virtual void DoBegin() { // Note that DoPrepare() and DoBegin() should NOT be combined. // Reason: Encoding of commandline parameters happen as part // of DoPrepare(). If they are combined, the first command's // DoBegin() will be called before the next command's // DoPrepare(). Since BeginProcessing() can write objects // to the downstream commandlet, it will end up calling // DoExecute() (from Pipe.Add()) before DoPrepare. if (!RanBeginAlready) { RanBeginAlready = true; Pipe oldErrorOutputPipe = _context.ShellFunctionErrorOutputPipe; CommandProcessorBase oldCurrentCommandProcessor = _context.CurrentCommandProcessor; try { // // On V1 the output pipe was redirected to the command's output pipe only when it // was already redirected. This is the original comment explaining this behaviour: // // NTRAID#Windows Out of Band Releases-926183-2005-12-15 // MonadTestHarness has a bad dependency on an artifact of the current implementation // The following code only redirects the output pipe if it's already redirected // to preserve the artifact. The test suites need to be fixed and then this // the check can be removed and the assignment always done. // // However, this makes the hosting APIs behave differently than commands executed // from the command-line host (for example, see bugs Win7:415915 and Win7:108670). // The RedirectShellErrorOutputPipe flag is used by the V2 hosting API to force the // redirection. // if (this.RedirectShellErrorOutputPipe || _context.ShellFunctionErrorOutputPipe != null) { _context.ShellFunctionErrorOutputPipe = this.commandRuntime.ErrorOutputPipe; } _context.CurrentCommandProcessor = this; using (commandRuntime.AllowThisCommandToWrite(true)) { using (ParameterBinderBase.bindingTracer.TraceScope( "CALLING BeginProcessing")) { SetCurrentScopeToExecutionScope(); if (Context._debuggingMode > 0 && !(Command is PSScriptCmdlet)) { Context.Debugger.CheckCommand(this.Command.MyInvocation); } Command.DoBeginProcessing(); } } } catch (Exception e) { // This cmdlet threw an exception, so // wrap it and bubble it up. throw ManageInvocationException(e); } finally { _context.ShellFunctionErrorOutputPipe = oldErrorOutputPipe; _context.CurrentCommandProcessor = oldCurrentCommandProcessor; RestorePreviousScope(); } } }