簡體   English   中英

格式化托管PowerShell的輸出

[英]Formatting Output of Hosted PowerShell

我在這里找到了一個C#示例,它從主機應用程序異步調用PowerShell腳本(在文件夾第6章 - 閱讀事件中),並嘗試在Windows窗體應用程序中使用它。

我有一個按鈕(button1)來啟動PowerShell腳本,textBox1是輸入腳本而textBox2是顯示腳本輸出。 這是我目前的代碼:

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);
            }
        }
    }
}

代碼有效,但我在處理輸出時遇到問題。 Pipeline.Output.Read()返回PSObject的一個實例,因此ToString()為不同的對象返回不同的東西。 例如,如果我使用此PowerShell命令:

Get-ChildItem

輸出是:

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

如果我使用:

Get-Process

輸出是:

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

我可以使用返回的PSObject實例來構造輸出,但它會很好如果我可以使用現有的PowerShell格式並獲得與控制台中相同的輸出。 當我運行應用程序並檢查Runspace.RunspaceConfiguration.Formats時,計數為9,並且存在DotNetTypes.format.ps1xml,但我不知道如何應用該格式。

我注意到如果我在腳本的末尾添加Out-String:

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

輸出的格式與標准PowerShell控制台中的格式相同。 這有效,但是如果我運行一個帶有長輸出的腳本需要一些時間來執行:

gci d:\ -recurse

Pipeline.Output.DataReady事件僅引發一次(在執行結束Out-String之后),然后才將輸出添加到文本框中。

有沒有辦法在托管的PowerShell實例中使用標准的PowerShell輸出格式?

如果你在out-string上使用-stream參數,我想你會發現它不會阻塞。

此外,如果您實際構建主機(實現主機接口,包括UI和可能的rawui),您將實現處理“標准”主機輸出的方法。

您也可以嘗試使用out-default而不是out-string。 我知道在自托管環境中我經常使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM