Powershell/C#: Invoking a pipeline asynchronously & displaying the results

久未见 提交于 2019-12-29 09:34:15

问题


As per this sample - http://msdn.microsoft.com/en-us/library/windows/desktop/ee706590(v=vs.85).aspx,

I am trying to invoke my script in an async way. But, at the same time, I want to give feedback to the GUI on the set of operations happening i.e. want to spit the Write-verbose stuffs happening behind the scenes parallely on the GUI.

I am confused in achieving this - because I see there is a DataReady event on the PipelineReader object ? Is it possible to somehow consume that w.r.t the MSDN sample above such that I can show feedback on the GUI ?

Conceptually, I am not able to relate this sample with the DataReady event.


回答1:


Got it ! Here is the full code...

Add a Rich Textbox = txtOutput on a Form first & Add a reference to

C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll

    IAsyncResult _invokeResult; 

    PowerShell _ps = PowerShell.Create();

    delegate void SetOutput(string value);

    // Monitor the DataAdded
    _ps.Streams.Verbose.DataAdded += new EventHandler<DataAddedEventArgs>(Verbose_DataAdded);

    var sr = new StreamReader(@"C:\MyScript.ps1");
    _ps.AddScript(sr.ReadToEnd());
    _invokeResult = _ps.BeginInvoke<PSObject>(null, null, AsyncInvoke, null);


   void Verbose_DataAdded(object sender, DataAddedEventArgs e)
   {
       System.Diagnostics.Debug.Print( ((PSDataCollection<VerboseRecord>) sender)[e.Index].ToString()) ;

       if (txtOutput.InvokeRequired)
       {
           string msg = ((PSDataCollection<VerboseRecord>) sender)[e.Index].ToString();
           txtOutput.Invoke(new SetOutput(Execute), new object[] { msg} );
       }
   }



   void AsyncInvoke(IAsyncResult ar)
   {
       // end
       try
       {
           _ps.EndInvoke(ar);
       }
       catch (Exception ex)
       {
             // do something with the error...
       }
  }

private void Execute(string msg)
        {
            txtOutput.SelectionFont = new Font(txtOutput.SelectionFont.FontFamily, 9.0f);
            txtOutput.AppendText(msg);
            txtOutput.ScrollToCaret();
        }



回答2:


If you only want to output Write-Verbose output to the GUI then it would be easier to monitor the Streams.Verbose collection after the InvokeAsync. If you want to scan all the output then use the PipelineReader. Subscribe to its DataReady event and in that event handler do a NonBlockingRead to get the data.



来源:https://stackoverflow.com/questions/10723264/powershell-c-invoking-a-pipeline-asynchronously-displaying-the-results

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!