【问题标题】:How to capture a Powershell CmdLet's Object output when the CmdLet is programmatically Invoked from C#从 C# 以编程方式调用 CmdLet 时如何捕获 Powershell CmdLet 的对象输出
【发布时间】:2013-10-11 15:31:59
【问题描述】:

背景

  • 带有 SDK 的 PowerShell 3
  • 带有框架 4.5 的 C#

实施

我已经使用 PSHostUserInterface 实现了我自己的 PSHost 登录。 在 PSHostUserInterface 中,我覆盖了所有 Write... 方法并将其收集到一个用于输出的变量。

问题

在我的应用程序中,我调用了使用 WriteObject 作为其输出的 Cmdlet。在 PSHostUserInterface.Write... 方法中,我得到了除了这些 WriteObject 的输出之外的所有内容。 例如,我在常规 PowerShell 中看到了这一点:

这是命令输出的示例字符串

这里我们有来自 Cmdlet.WriteObject 函数的对象

这是命令输出的另一个字符串

这是我在应用程序的自定义 PSHost 中得到的:

这是命令输出的示例字符串

这是命令输出的另一个字符串

问题

如何在 C# 中获取 Cmdlet 的所有输出?

非常感谢

【问题讨论】:

  • 通常Pipeline.Invoke 的返回值是管道输出的可枚举(对于错误输出,请使用同一Pipeline 实例的Error 属性)。因此,请使用您用于在主机中执行 PSH 管道的代码更新您的问题。
  • 嗨,管道中根本没有Error。我不能只是简单地Pipeline.Invoke,因为我的 CmdLets 需要 UI。正因为如此,通过自定义 PSHostPSHostUserInterface 我可以覆盖用户交互并执行它们。

标签: c# powershell pshost


【解决方案1】:

我认为 Richard 的评论很到位。如果您使用 Pipeline.Invoke() 调用 cmdlet,则必须:

  • A) 使用这些对象再次调用 Pipeline.Invoke 并将它们通过管道传输到 Out-Default
  • B) 只需将命令Out-Default 附加到原始管道即可。这将告诉 PowerShell 将输出发送到显示器(并使用默认格式)。

通常,当您将管道输出的结果对象存储在 PowerShell 变量 $res = Get-Process 或 C# 中作为 Invoke() 的输出时,您处理的是实际的 .NET 对象。如果未捕获管道输出,则将这些对象格式化和呈现给主机是 PowerShell 将为您执行的另一个步骤。在这种情况下,PowerShell 有效地将 | Out-Default 附加到管道。

【讨论】:

  • 添加 Out-Default 有帮助。嗯,想知道为什么 Out-String 没有帮助......我也尝试一下“你正在处理实际的 .NET 对象”。非常感谢,标记为答案。
  • 当您使用Out-Default 时,PowerShell 会将对象呈现为字符串,然后写入主机。使用Out-String,PowerShell 会将对象呈现为字符串并将该字符串作为管道输出返回。从 pipeline.Invoke() 返回后显示它取决于您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多