Форматирование вывода размещенного PowerShell - PullRequest
5 голосов
/ 26 декабря 2010

Я нашел пример 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<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?

1 Ответ

3 голосов
/ 26 декабря 2010

Если вы используете параметр -stream для out-string, я думаю, вы обнаружите, что он не блокируется.

Кроме того, если вы действительно строите хост (реализуйте интерфейс хоста, включая интерфейсПользовательский интерфейс и, возможно, rawui), вы будете реализовывать методы для обработки «стандартного» вывода хоста.

Вы также можете попробовать использовать out-default вместо out-string.Я знаю, что в автономных средах я обычно использую это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...