I'm writing a C# GUI program that uses System.Management.Automation to execute powershell commands on an instance created at runtime, I need it to be a persistent powershell instance so I can send multiple commands and collect the output at runtime. This works as intended but i'm having some issues subscribing to the progress event. It only fires when I input faulty commands and writes that the progress is -1 percent complete.
When I input correct commands it doesn't fire at all. The error and output events work properly so i'm not sure what's going wrong.
I found two others having similar problems but their solutions didn't work for me, I linked them down below. Here's the code i'm using unsucessfully so far.
public class CodeHandler {
public static PowerShell psInstance;
public void init() {
//Create powershell instance
psInstance = PowerShell.Create();
}
public async Task < string > ExecutePowershellCommand(string script) {
psInstance.AddScript(script);
psInstance.AddCommand("Out-String");
PSDataCollection < PSObject > outputCollection = new PSDataCollection < PSObject > ();
outputCollection.DataAdded += outputCollection_DataAdded;
//The Part I Can't Get To Work
psInstance.Streams.Progress.DataAdded += (sender, eventargs) => {
PSDataCollection < ProgressRecord > progressRecords = (PSDataCollection < ProgressRecord > ) sender;
Console.WriteLine("!Progress is {0} percent complete", progressRecords[eventargs.Index].PercentComplete);
};
psInstance.Streams.Error.DataAdded += Error_DataAdded;
IAsyncResult result = psInstance.BeginInvoke < PSObject, PSObject > (null, outputCollection);
while (!result.IsCompleted) {
Console.WriteLine("Waiting for pipeline to finish...");
await Task.Delay(100);
}
PSInvocationState state = psInstance.InvocationStateInfo.State;
Console.WriteLine("Execution has stopped. The pipeline state: " + state);
if (state != PSInvocationState.Completed)
return string.Empty;
StringBuilder stringBuilder = new StringBuilder();
foreach(PSObject outputItem in outputCollection) {
stringBuilder.AppendLine(outputItem.BaseObject.ToString());
Console.WriteLine(outputItem.BaseObject.ToString());
}
return stringBuilder.ToString();
}
}
References:
Getting Write-Progress -PercentComplete status from within C#
Progressstream, then the behavior you describe is expected