Форматирование вывода размещенной оболочки PowerShell

Я нашел пример C # здесь асинхронного вызова сценария PowerShell из ведущего приложения (в папке Глава 6 - Чтение с событиями) и пытаюсь использовать его в приложении Windows Forms .

У меня есть кнопка (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 output = 
                sender as PipelineReader;

            if (output != null)
            {
                while (output.Count > 0)
                {
                    SetText(output.Read().ToString());
                }
                return;
            }

            PipelineReader error = 
                sender as PipelineReader;

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

Код работает, но у меня проблема с обработкой вывода. Трубопровод. 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?

5
задан 26 December 2010 в 16:40
поделиться