Захват вывода Powershell в C# после выдачи Pipeline.Invoke

StackOverflow https://stackoverflow.com/questions/1233640

  •  22-07-2019
  •  | 
  •  

Вопрос

Я запускаю тестовый сценарий Powershell из приложения C#.Сценарий может завершиться неудачно из-за неправильного командлета, из-за которого Pipe.Invoke() выдаст исключение.

Я могу собрать всю необходимую мне информацию об исключении, но мне хотелось бы иметь возможность отображать выходные данные сценария до этого момента.Мне не повезло, так как при возникновении исключения результаты кажутся нулевыми.

Есть ли что-то, что мне не хватает?Спасибо!

m_Runspace = RunspaceFactory.CreateRunspace();
m_Runspace.Open();
Pipeline pipe = m_Runspace.CreatePipeline();
pipe.Commands.AddScript(File.ReadAllText(ScriptFile));
pipe.Commands.Add("Out-String");
try {
   results = pipe.Invoke();
}
catch (System.Exception)
{
   m_Runspace.Close();
   // How can I get to the Powershell output that comes before the exception?
}
Это было полезно?

Решение 2

Решение, которое я использовал в итоге, заключалось в реализации собственного PSHost для обработки выходных данных PowerShell. Первоначальная информация для этого была получена от http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx в " Построении собственного хоста PS " раздел.

В моем случае это также требовало использования пользовательского PSHostRawUserInterface.

Вот краткий обзор того, что было сделано. Я перечислил только те функции, которые я на самом деле реализовал, но многие из них содержат только throw new NotImplementedException ();

private class myPSHost : PSHost
{
   (Same as what the above link mentions)
}
private class myPSHostUI : PSHostUserInterface
{
   private myPSHostRawUI rawui = new myPSHostRawUI();

   public override void Write // all variations
   public override PSHostRawUserInterface RawUI { get { return rawui; } }

}
private class myPSHostRawUI : PSHostRawUserInterface
{
   public override ConsoleColor ForegroundColor
   public override ConsoleColor BackgroundColor
   public override Size BufferSize
}

Другие советы

Не уверен, что это полезно. Я предполагаю, что вы работаете с V1. Этот подход V2 не выбрасывает и печатает результат:

Hello World
67 errors

string script = @"
  'Hello World'
  ps | % {
    

Не уверен, что это полезно. Я предполагаю, что вы работаете с V1. Этот подход V2 не выбрасывает и печатает результат:

<*>.name | out-string1 } "; PowerShell powerShell = PowerShell.Create(); powerShell.AddScript(script); var results = powerShell.Invoke(); foreach (var item in results) { Console.WriteLine(item); } if (powerShell.Streams.Error.Count > 0) { Console.WriteLine("{0} errors", powerShell.Streams.Error.Count); }

У меня та же проблема.Самый простой способ получить выходные данные, когда Pipe.Invoke() генерирует исключение, — использовать Invoke (ввод IEnumerable, вывод IList)

Пример показывает, как получить все выходные данные, ошибки, убывания и т. д.в правильном порядке

PowerShell-скрипт

Write-Output "Hello world" 
Write-Error "Some error"
Write-Warning "Some warning"
throw "Some exception"

С#

List<string> RunLog = new List<string>(); 

using (System.Management.Automation.PowerShell psInstance = System.Management.Automation.PowerShell.Create())

{
    psInstance.AddScript(_Script);

psInstance.Streams.Error.DataAdded += (sender, args) =>
{
    ErrorRecord err = ((PSDataCollection<ErrorRecord>)sender)[args.Index];
    RunLog.Add($"ERROR: {err}");
};

psInstance.Streams.Warning.DataAdded += (sender, args) =>
{
    WarningRecord warning = ((PSDataCollection<WarningRecord>)sender)[args.Index];
    RunLog.Add($"WARNING: {warning}");
};

... etc ...

var result = new PSDataCollection<PSObject>();
result.DataAdded += (sender, args) =>
{
    PSObject output = ((PSDataCollection<PSObject>)sender)[args.Index];
    RunLog.Add($"OUTPUT: {output}");
};

try
{
    psInstance.Invoke(null, result);
}
catch(Exception ex)
{
    RunLog.Add($"EXCEPTION: {ex.Message}");
}                                                
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top