2009-08-05 8 views
11

C# uygulamasından bir Powershell test komut dosyası çalıştırıyorum. Komut dosyası, bir istisna atmak için pipe.Invoke() işlevine neden olan bozuk bir cmdlet nedeniyle başarısız olabilir.Pipeline.Invoke, C# uygulamasında Powershell çıktısını yakalama

İstisna ile ilgili gereken tüm bilgileri yakalayabiliyorum, ancak komut dosyasının çıktısını bu noktaya kadar görüntülemek istiyorum. Bir istisna atıldığında sonuç null gibi göründüğünden şansım olmadı.

Eksik olduğum bir şey var mı? Teşekkürler!

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

cevap

8

çözüm PowerShell çıkışını işlemek için kendi PSHost uygulamaktı. Bunun için ilk bilgi, "Bir özel PS ana bilgisayarı oluşturma" bölümünde http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx'dan geldi.

Benim durumumda da, özel bir PSHostRawUserInterface kullanmasını gerektirdi.

Yapılmış olanlara genel bakış. Sadece gerçekten özümsediğim işlevi listeledim, ancak yeni bir tane yeni 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

Güzel bir, tam olarak aradığım şey. Teşekkürler. –

14

Bu yardımcı olup olmadığından emin değil. Sanırım V1 kullanıyorsun. Bu V2 yaklaşım atmak ve sonucu yazdırır değildir: Ben kullanarak sona erdi

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

doğru, ben kullanıyorum edilir Güç kabuk v1. –

0

Aynı problemim var. pipe.Invoke() bir istisna doğru sırayla vb azalan, tüm çıkış, hatayı nasıl Invoke(IEnumerable input, IList output)

Örnek kullanmak gösterir olduğu atar kolay yolu çıkışı almak için

PowerShell komut

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