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?
}
War es hilfreich?

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}");
}                                                
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top