Call a PowerShell script from C # in the execution space and get the line number where the error occurred

I have several PowerShell hosts in C #, from where I run the PowerShell script code. The code is below from the host in Add0In for Visual Studio. The problem is that if an error occurs in the PowerShell script code that does not know the file number and file line of the PowerShell script where the error occurred.

My hosting code looks like this:

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

At first I had my own script in the script code variable, now I will first write the code in a temporary .ps1 file so that I can report linenumbers in this file. But I can’t find how to execute the code in the file so that I can get the file name and line numbers in case of errors.

Any ideas?

+4
source share
1 answer

This should bring you to the right place:

 //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:

Like the information I wrote in a comment, please also look at this book: PowerShell Professional Programming

I found this book invaluable when I first started programming the host for the PowerShell runtime. It was written by some of the PowerShell developers.

+6
source

Source: https://habr.com/ru/post/1306776/


All Articles