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