在运行空间中从c#调用PowerShell脚本,并获取发生错误的行号

Ser*_*ver 4 c# powershell

我在C#中有一些PowerShell主机,我从中执行PowerShell脚本代码.下面的代码来自Visual Studio的Add0In中的主机.问题是,如果PowerShell脚本代码中发生错误,我不知道发生错误的PowerShell脚本文件的文件和行号.

我的托管代码如下:

        public Exception Execute(string scriptcode, Hashtable variables)
    {
        Runspace runspace = null;
        Pipeline pipeline = null;
        PipelineStateInfo info = null;

        try
        {
            // Make our output window active
            Logger.ShowOutputWindow();

            // Create the runspace and stuff.
            runspace = RunspaceFactory.CreateRunspace(host);
            pipeline = runspace.CreatePipeline();

            runspace.Open();

            // Add our scriptcode to the pipeline
            pipeline.Commands.Add(new Command(scriptcode, true));

            // We don't want to get PSObjects out of the pipeline, output result as string in default way
            pipeline.Commands.Add(new Command("Out-Default", true));

            // Set up global variables
            FillVariables(runspace, variables);

            SetUpOutputStreams(pipeline);


            // Run the scriptcode
            Collection<PSObject> psOutput = pipeline.Invoke();

            // Did it complete ok?
            info = pipeline.PipelineStateInfo;
            if (info.State != PipelineState.Completed)
            {
                return info.Reason;
            }
            else
            {
                return null; // succesful!
            }
        }
        catch (Exception ex)
        {
            return ex;
        }
    }
Run Code Online (Sandbox Code Playgroud)

首先,我在scriptcode变量中创建了脚本,现在我首先将代码写入临时的.ps1文件,以便我可以报告该文件中的亚麻布.但是我找不到如何在文件中执行代码,因此可以在出错时检索文件名和行号.

有任何想法吗?

Jam*_*ran 7

这应该让你在正确的地方:

//invoke pipeline
collection = pipeline.Invoke();

// check for errors (non-terminating)
if (pipeline.Error.Count > 0)
{
  //iterate over Error PipeLine until end
  while (!pipeline.Error.EndOfPipeline)
  {
    //read one PSObject off the pipeline
    var value = pipeline.Error.Read() as PSObject;
    if (value != null)
    {
      //get the ErrorRecord
      var r = value.BaseObject as ErrorRecord;
      if (r != null)
      {
        //build whatever kind of message your want
        builder.AppendLine(r.InvocationInfo.MyCommand.Name + " : " + r.Exception.Message);
        builder.AppendLine(r.InvocationInfo.PositionMessage);
        builder.AppendLine(string.Format("+ CategoryInfo: {0}", r.CategoryInfo));
        builder.AppendLine(
        string.Format("+ FullyQualifiedErrorId: {0}", r.FullyQualifiedErrorId));
      }
    }
  }
  return builder.ToString();
}
Run Code Online (Sandbox Code Playgroud)

更新:

除了我在评论中写的信息外,还请看这本书:专业的PowerShell编程

当我第一次开始为PowerShell运行时编程主机时,我发现这本书非常宝贵.它是由一些PowerShell开发人员编写的.