2009-08-05 9 views
11

Je cours un script de test Powershell à partir d'une application C#. Le script peut échouer en raison d'une mauvaise cmdlet qui provoque pipe.Invoke() pour lancer une exception.Capture de la sortie Powershell en C# après le lancement de Pipeline.Invoke

Je suis capable de capturer toutes les informations dont j'ai besoin sur l'exception, mais j'aimerais pouvoir afficher la sortie du script jusqu'à ce point. Je n'ai pas eu de chance car les résultats semblent être Nuls lorsqu'une exception est levée.

Y a-t-il quelque chose qui me manque? Merci!

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

Répondre

8

La solution que je fini par utiliser était de mettre en œuvre notre propre PSHost pour gérer la sortie de PowerShell. Les informations initiales à cet égard proviennent de http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx dans la section "Création d'un hôte PS personnalisé".

Dans mon cas, il a fallu également utiliser un PSHostRawUserInterface personnalisé.

Voici un aperçu rapide de ce qui a été fait. J'ai seulement énuméré la fonction que j'ai réellement impliquée, mais il y en a beaucoup qui contiennent juste throw new 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 
} 
+0

Nice, exactement ce que je cherchais. Merci. –

14

Vous ne savez pas si cela est utile. Je devine que vous utilisez V1. Cette approche V2 ne jette pas et affiche le résultat:

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); 
} 
+0

Vous avez raison, je suis en utilisant l'énergie shell v1. –

0

J'ai le même problème. La meilleure façon d'obtenir une sortie quand pipe.Invoke() renvoie une exception est d'utiliser Invoke(IEnumerable input, IList output)

exemple montre comment obtenir toutes les sorties, erreur, etc. décroissante dans l'ordre

script PowerShell

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}"); 
}             
} 
Questions connexes