【问题标题】:How to read PowerShell exit code via c#如何通过 C# 读取 PowerShell 退出代码
【发布时间】:2016-10-14 23:19:34
【问题描述】:

我正在使用System.Management.Automation.Runspaces 来执行 PowerShell 脚本。 有没有可以读取给定脚本的退出代码的选项?

using System.IO;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.Management.Automation;

namespace PowerShell
{
    public class PowerShellExecuter
    {
        public Collection<PSObject> RunPsScript(string psScriptFile)
        {
            string psScript;
            if (File.Exists(psScriptFile))
            {
                psScript = File.ReadAllText(psScriptFile);
            }
            else
            {
                throw new FileNotFoundException("Wrong path for the script file");
            }
            Runspace runSpace = RunspaceFactory.CreateRunspace();
            runSpace.Open();

            RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runSpace);
            runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");

            Pipeline pipeLine = runSpace.CreatePipeline();
            pipeLine.Commands.AddScript(psScript);
            pipeLine.Commands.Add("Out-String");

            Collection<PSObject> returnObjects = pipeLine.Invoke();
            runSpace.Close();

            return returnObjects;
        }
    }
}

【问题讨论】:

    标签: c# powershell


    【解决方案1】:

    PowerShell 命令具有比整数退出代码更丰富的错误机制。有一个错误流出现非终止错误。终止错误会导致抛出异常,因此您需要处理这些异常。以下代码展示了如何使用这两种机制:

    using System;
    using System.Collections.ObjectModel;
    using System.Management.Automation;
    
    namespace PowerShellRunspaceErrors
    {
        class Program
        {
            private static PowerShell s_ps;
    
            static void Main(string[] args)
            {
                s_ps = PowerShell.Create();
                ExecuteScript(@"Get-ChildItem c:\xyzzy");
                ExecuteScript("throw 'Oops, I did it again.'");
            }
    
            static void ExecuteScript(string script)
            {
                try
                {
                    s_ps.AddScript(script);
                    Collection<PSObject> results = s_ps.Invoke();
                    Console.WriteLine("Output:");
                    foreach (var psObject in results)
                    {
                        Console.WriteLine(psObject);
                    }
                    Console.WriteLine("Non-terminating errors:");
                    foreach (ErrorRecord err in s_ps.Streams.Error)
                    {
                        Console.WriteLine(err.ToString());
                    }
                }
                catch (RuntimeException ex)
                {
                    Console.WriteLine("Terminating error:");
                    Console.WriteLine(ex.Message);
                }
            }
        }
    }
    

    如果你运行这个程序,它会输出:

    Output:
    Non-terminating errors:
    Cannot find path 'C:\xyzzy' because it does not exist.
    Terminating error:
    Oops, I did it again.
    Press any key to continue . . .
    

    【讨论】:

      【解决方案2】:

      进程返回退出代码,而不是 PowerShell Runspaces

      据我所知,捕获Runspace 状态的最佳方法是订阅Runspace.StateChanged 事件,这将为您提供RunspaceStateInfo 来处理。 RunspaceStateInfo 上有两个有用的属性:ReasonState

      http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.runspacestateinfo_members(v=vs.85).aspx

      【讨论】:

        【解决方案3】:

        就像向刚刚创建的运行空间询问值一样简单:

        s_ps.AddScript("$LASTEXITCODE");
        results = s_ps.Invoke();
        int.TryParse(results[0].ToString(),out valorSortida);
        

        【讨论】:

        • 这让我走上了正轨。 HadErrors 和 Streams.Error 并不意味着小队,它完全取决于脚本如何处理错误流(如果有的话)以及它是否处理异常。我现在清除输出集合并执行另一个单行程序来输出一个我知道的变量来保存我的脚本的结果(你演示的方式)。我找到的唯一可靠的方法。我宁愿有一种方法来获取结束脚本的 Exit 命令提供的参数,但这也有效。谢谢!
        • 这不起作用,至少在我解释它的方式上,因为这个答案是模糊或不完整的。您能否提供一个完整的示例或解释它是如何使用的?
        猜你喜欢
        • 2014-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-16
        • 2016-05-20
        • 2023-03-27
        • 2012-03-09
        • 2016-10-08
        相关资源
        最近更新 更多