Formatting Hosted PowerShell Output

I found a C # example here for asynchronously calling a PowerShell script from the main application (in the Chapter 6 folder - Reading with events) and I am trying to use it in a Windows Forms application.

I have a button (button1) to run a PowerShell script, textBox1 should enter a script, and textBox2 displays the output of the script. Here is my current code:

using System; using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Windows.Forms; namespace PSTestApp { delegate void SetTextDelegate(string text); public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { textBox2.Text = ""; Runspace runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); Pipeline pipeline = runspace.CreatePipeline(textBox1.Text); pipeline.Output.DataReady += new EventHandler(HandleDataReady); pipeline.Error.DataReady += new EventHandler(HandleDataReady); pipeline.InvokeAsync(); pipeline.Input.Close(); } private void HandleDataReady(object sender, EventArgs e) { PipelineReader<PSObject> output = sender as PipelineReader<PSObject>; if (output != null) { while (output.Count > 0) { SetText(output.Read().ToString()); } return; } PipelineReader<object> error = sender as PipelineReader<object>; if (error != null) { while (error.Count > 0) { SetText(error.Read().ToString()); } return; } } private void SetText(string text) { if (textBox2.InvokeRequired) { SetTextDelegate d = new SetTextDelegate(SetText); this.Invoke(d, new Object[] { text }); } else { textBox2.Text += (text + Environment.NewLine); } } } } 

The code works, but I have a problem processing the output. Pipeline.Output.Read () returns an instance of the PSObject, so ToString () returns different things for different objects. For example, if I use this PowerShell command:

 Get-ChildItem 

output:

 PSTestApp.exe PSTestApp.pdb PSTestApp.vshost.exe PSTestApp.vshost.exe.manifest 

and if I use:

 Get-Process 

output:

 ... System.Diagnostics.Process (csrss) System.Diagnostics.Process (ctfmon) System.Diagnostics.Process (devenv) System.Diagnostics.Process (devenv) ... 

I could use returned PSObject instances to build the output, but it would be nice. If I could use the existing PowerShell formatting and get the same result as in the console. When I launch the application and check Runspace.RunspaceConfiguration.Formats, the number is 9 and DotNetTypes.format.ps1xml is present, but I do not know how to apply the format.

I noticed that if I add an Out-String to the end of the script:

 ... Pipeline pipeline = runspace.CreatePipeline(textBox1.Text); pipeline.Commands.Add("Out-String"); ... 

output is formatted in the same way as in the standard PowerShell console. This works, but if I run the script with a long output, it takes a while to execute:

 gci d:\ -recurse 

The Pipeline.Output.DataReady event is generated only once (after the Out-String is completed), and only after that the output is added to the text field.

Is there a way to use standard PowerShell output formatting in a hosted PowerShell instance?

+4
source share
1 answer

If you use the -stream option in out-string, I think you will find that it is not blocking.

In addition, if you are actually creating a host (implementing a host interface, including a user interface and possibly rawui), you will implement methods to handle the โ€œstandardโ€ host output.

You can also try using out-default instead of out-string. I know that in self-service environments I usually use this.

+3
source

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


All Articles