问题
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