2010-04-13 37 views
4

我在C#中執行PowerShell腳本代碼的地方有一些PowerShell主機。下面的代碼來自於AddOIn for Visual Studio中的主機。問題是,如果在PowerShell腳本代碼中發生錯誤,我不知道發生錯誤的PowerShell腳本文件的文件和行號。從運行空間中的c#調用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; 
     } 
    } 

首先,我有我的劇本在腳本代碼變量,我現在先寫代碼到一個臨時文件名爲.psl這樣我就可以在該文件linenumbers報告。但我找不到如何在文件中執行代碼,以便在發生錯誤時可以檢索文件名和行號。

任何想法?

+0

關於它的任何解決方案和完整的源代碼? – Kiquenet 2012-05-25 08:19:17

回答

6

這應該讓你在正確的地方:

//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(); 
} 

UPDATE:

除了我在評論中寫道的信息,也請看看這本書:Professional PowerShell Programming

我當我第一次開始編寫PowerShell運行時的主機時,發現這本書是無價的。它是由一些PowerShell開發人員編寫的。

+1

奇怪的是,如果發生錯誤,例如使用throw或1/0,pipeline.Invoke()將引發異常,並且錯誤集合爲空。所以我沒有得到調用信息。它也不會跟蹤工作(set-psdebug -trace 1)。 – 2010-04-21 07:22:57

+0

是的。此代碼將捕獲PowerShell表面的任何錯誤,PowerShell不會拋出異常。那些必須在調用調用周圍的正常try catch塊中捕獲。我通常會遇到NullReferenceException和特定情況下捕獲的一些特定的PowerShell異常。 追蹤是另一條管線。目前我沒有SDK在我面前,但我相信它以相同的方式訪問。 – 2010-04-21 14:52:07

相關問題