12

我正在从 C# 应用程序运行 Powershell 测试脚本。由于错误的 cmdlet 导致 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?
}
4

3 回答 3

16

不确定这是否有帮助。我猜你正在运行V1。这种 V2 方法不会抛出并打印结果:

Hello World
67 errors

string script = @"
  'Hello World'
  ps | % {
    $_.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);
}
于 2009-08-06T00:18:43.787 回答
9

我最终使用的解决方案是实现我们自己的 PSHost 来处理 PowerShell 的输出。最初的信息来自http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx in the "Building自定义 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
}
于 2009-09-25T13:34:08.257 回答
4

我也有同样的问题。当 pipe.Invoke() 抛出异常时获取输出的最简单方法是使用Invoke(IEnumerable input, IList output)

示例显示如何以正确的顺序获取所有输出、错误、衰减等

PowerShell 脚本

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

C#

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}");
}                                                
}
于 2017-08-28T11:15:54.680 回答