Erfassen Powershell Ausgang in C # nach Pipeline.Invoke wirft
-
22-07-2019 - |
Frage
Ich bin mit einem Powershell-Testskript aus einer C # -Anwendung. Das Skript kann aufgrund eines schlechten Cmdlets scheitern, die bewirkt, dass pipe.Invoke () eine Ausnahme werfen.
Ich bin die Lage, alle Informationen, die ich über die Ausnahme brauchen zu erfassen, aber ich möchte in der Lage sein, die Ausgabe bis zu diesem Punkt Skript angezeigt werden soll. Ich habe kein Glück gehabt, da Ergebnisse erscheinen null zu sein, wenn eine Ausnahme ausgelöst wird.
Gibt es etwas, was ich vermisst habe? Dank!
m_Runspace = RunspaceFactory.CreateRunspace();
m_Runspace.Open();
Pipeline pipe = m_Runspace.CreatePipeline();
pipe.Commands.AddScript(File.ReadAllText(ScriptFile));
pipe.Commands.Add("Out-String");
try {
results = pipe.Invoke();
}
catch (System.Exception)
{
m_Runspace.Close();
// How can I get to the Powershell output that comes before the exception?
}
Lösung 2
Die Lösung, die ich am Ende war mit eigener PSHost zu implementieren Powershell Ausgabe zu handhaben. Die ersten Informationen dazu kam von http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx im Abschnitt "ein benutzerdefinierten PS Host Gebäude".
In meinem Fall ist es erforderte eine benutzerdefinierte PSHostRawUserInterface auch verwendet wird.
Hier ist die schnelle Übersicht über, was getan wurde. Ich habe nur aufgeführt, die Funktion, die ich eigentlich implimented, aber es gibt viele, die einfach sind, enthalten werfen neue NotImplementedException ();
private class myPSHost : PSHost
{
(Same as what the above link mentions)
}
private class myPSHostUI : PSHostUserInterface
{
private myPSHostRawUI rawui = new myPSHostRawUI();
public override void Write // all variations
public override PSHostRawUserInterface RawUI { get { return rawui; } }
}
private class myPSHostRawUI : PSHostRawUserInterface
{
public override ConsoleColor ForegroundColor
public override ConsoleColor BackgroundColor
public override Size BufferSize
}
Andere Tipps
Nicht sicher, ob dies hilfreich ist. Ich vermute, Sie V1 ausgeführt werden. Dieser V2 Ansatz nicht werfen und druckt das Ergebnis:
Hello World
67 errors
string script = @"
'Hello World'
ps | % {
$_.name | out-string1
}
";
PowerShell powerShell = PowerShell.Create();
powerShell.AddScript(script);
var results = powerShell.Invoke();
foreach (var item in results)
{
Console.WriteLine(item);
}
if (powerShell.Streams.Error.Count > 0)
{
Console.WriteLine("{0} errors", powerShell.Streams.Error.Count);
}
Ich habe das gleiche Problem. Der einfachste Weg, Ausgabe zu erhalten, wenn pipe.Invoke () wirft eine Ausnahme zu verwenden ist Invoke (IEnumerable Eingang, Ausgang IList)
Beispiel zeigt, wie alle Ausgaben, Fehler zu erhalten, abnehmend usw. in der richtigen Reihenfolge
Powershell-Skript
Write-Output "Hello world"
Write-Error "Some error"
Write-Warning "Some warning"
throw "Some exception"
C #
List<string> RunLog = new List<string>();
using (System.Management.Automation.PowerShell psInstance = System.Management.Automation.PowerShell.Create())
{
psInstance.AddScript(_Script);
psInstance.Streams.Error.DataAdded += (sender, args) =>
{
ErrorRecord err = ((PSDataCollection<ErrorRecord>)sender)[args.Index];
RunLog.Add($"ERROR: {err}");
};
psInstance.Streams.Warning.DataAdded += (sender, args) =>
{
WarningRecord warning = ((PSDataCollection<WarningRecord>)sender)[args.Index];
RunLog.Add($"WARNING: {warning}");
};
... etc ...
var result = new PSDataCollection<PSObject>();
result.DataAdded += (sender, args) =>
{
PSObject output = ((PSDataCollection<PSObject>)sender)[args.Index];
RunLog.Add($"OUTPUT: {output}");
};
try
{
psInstance.Invoke(null, result);
}
catch(Exception ex)
{
RunLog.Add($"EXCEPTION: {ex.Message}");
}
}