2010-12-26 4 views
4

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

У меня есть кнопка (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 для const ruct выход, но было бы неплохо. Если бы я мог использовать существующее форматирование 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?

ответ

3

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

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

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

+0

Отлично, спасибо за ответ. –

Смежные вопросы