C # PowerShell I / O Modifier Modified When Piping Is Closed and Located

I am calling powershell script from C #. The script is quite small and represents "gps; $ host.SetShouldExit (9)", which lists the process and then sends back the exit code that should be captured by the PSHost object.

The problem is when the pipeline is stopped and removed, the PSHost output collector still seems to be writing and populating. Therefore, when I try to copy it to my own output object, it gets rid of the OutOfMemoryException when I try to iterate over it. Sometimes it will be except when the message has been changed in the collection. Here is the code.

 private void ProcessAndExecuteBlock(ScriptBlock Block)
   {
       Collection<PSObject> PSCollection = new Collection<PSObject>();
       Collection<Object> PSErrorCollection = new Collection<Object>();
       Boolean Error = false;
       int ExitCode=0;

       //Send for exection. 
       ExecuteScript(Block.Script);

       // Process the waithandles. 
       while (PExecutor.PLine.PipelineStateInfo.State  == PipelineState.Running)
       {
           // Wait for either error or data waithandle. 
           switch (WaitHandle.WaitAny(PExecutor.Hand))
           {
               // Data
               case 0:
                   Collection<PSObject> data =   PExecutor.PLine.Output.NonBlockingRead();
                   if (data.Count  > 0)
                   {
                       for (int cnt = 0; cnt <= (data.Count-1); cnt++)
                       {
                           PSCollection.Add(data[cnt]); 
                       }
                   }

                   // Check to see if the pipeline has been closed. 
                   if (PExecutor.PLine.Output.EndOfPipeline)
                   { 
                       // Bring back the exit code. 
                       ExitCode = RHost.ExitCode; 
                   }
                   break;
               case 1:
                   Collection<object> Errordata = PExecutor.PLine.Error.NonBlockingRead();
                   if (Errordata.Count > 0)
                   {
                       Error = true;
                       for (int count = 0; count <= (Errordata.Count - 1); count++)
                       {
                           PSErrorCollection.Add(Errordata[count]);
                       }
                   }
                   break;
           }
       }

       PExecutor.Stop();

       // Create the Execution Return block
       ExecutionResults ER = new ExecutionResults(Block.RuleGuid,Block.SubRuleGuid, Block.MessageIdentfier);
       ER.ExitCode = ExitCode;

       // Add in the data results.
       lock (ReadSync)
       {
           if (PSCollection.Count > 0)
           {
               ER.DataAdd(PSCollection);
           }
       }

       // Add in the error data if any.
       if (Error)
       {
           if (PSErrorCollection.Count > 0)
           {
               ER.ErrorAdd(PSErrorCollection);
           }
           else
           {
               ER.InError = true;
           }
       }

       // We have finished, so enque the block back. 
       EnQueueOutput(ER);
   }

and this is the PipelineExecutor class that sets up the pipeline to execute.

public class PipelineExecutor
{
    private Pipeline pipeline;
    private WaitHandle[] Handles;

    public Pipeline PLine
    {
        get { return pipeline; }
    }

    public WaitHandle[] Hand 
    {
        get { return Handles; }
    }

    public PipelineExecutor(Runspace runSpace, string command)
    {       
        pipeline = runSpace.CreatePipeline(command);
        Handles = new WaitHandle[2];
        Handles[0] = pipeline.Output.WaitHandle;
        Handles[1] = pipeline.Error.WaitHandle;
    }

    public void Start()
    {
        if (pipeline.PipelineStateInfo.State == PipelineState.NotStarted)
        {
            pipeline.Input.Close();
            pipeline.InvokeAsync();
        }
    }

    public void Stop()
    {
        pipeline.StopAsync();
    }
}

DataAdd, .

    public void DataAdd(Collection<PSObject> Data)
    {
        foreach (PSObject Ps in Data)
        {
            Data.Add(Ps);
        }
    }

for Data.Add, 600k +, , gps , . .

.

+3
1

. , , .. Doh!.

0

Source: https://habr.com/ru/post/1745598/


All Articles