【问题标题】:Capturing Powershell output in C# after Pipeline.Invoke throwsPipeline.Invoke 抛出后在 C# 中捕获 Powershell 输出
【发布时间】:2009-08-05 14:31:43
【问题描述】:

我正在从 C# 应用程序运行 Powershell 测试脚本。该脚本可能会由于导致 pipe.Invoke() 引发异常的错误 cmdlet 而失败。

我能够捕获我需要的关于异常的所有信息,但我希望能够显示该脚本的输出。我没有任何运气,因为抛出异常时结果似乎为空。

我有什么遗漏吗?谢谢!

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?
}

【问题讨论】:

    标签: c# powershell powershell-1.0


    【解决方案1】:

    不确定这是否有帮助。我猜你正在运行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);
    }
    

    【讨论】:

      【解决方案2】:

      我最终使用的解决方案是实现我们自己的 PSHost 来处理 PowerShell 的输出。这方面的初始信息来自“构建自定义 PS 主机”部分中的 http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx

      在我的情况下,它确实需要使用自定义 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
      }
      

      【讨论】:

      • 不错,正是我想要的。谢谢。
      【解决方案3】:

      我也有同样的问题。 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}");
      }                                                
      }
      

      【讨论】:

        猜你喜欢
        • 2010-10-29
        • 2018-05-01
        • 2011-01-26
        • 2012-05-10
        • 1970-01-01
        • 2018-06-09
        • 2023-03-25
        • 1970-01-01
        • 2010-11-20
        相关资源
        最近更新 更多