2009-08-05 35 views
11

Tôi đang chạy tập lệnh thử Powershell từ ứng dụng C#. Kịch bản có thể thất bại do một lệnh ghép ngắn gây ra pipe.Invoke() để ném một ngoại lệ.Ghi lại đầu ra của Powershell trong C# sau khi đường ống dẫn.Invoke ném

Tôi có thể nắm bắt tất cả thông tin tôi cần về ngoại lệ, nhưng tôi muốn có thể hiển thị đầu ra của tập lệnh đến thời điểm đó. Tôi đã không có bất kỳ may mắn kể từ khi kết quả dường như là null khi một ngoại lệ được ném.

Có điều gì tôi thiếu không? Cảm ơn!

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

Trả lời

8

Giải pháp mà tôi đã sử dụng là triển khai PSHost của riêng chúng tôi để xử lý đầu ra của PowerShell. Thông tin ban đầu cho điều này đến từ http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx trong phần "Tạo máy chủ lưu trữ PS tùy chỉnh".

Trong trường hợp của tôi, nó cũng yêu cầu sử dụng PSHostRawUserInterface tùy chỉnh.

Dưới đây là tổng quan nhanh về những gì đã được thực hiện. Tôi đã chỉ liệt kê hàm tôi đã thực sự implimented, nhưng có rất nhiều hàm chỉ chứa ném mới 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

Đẹp nhất, chính xác những gì tôi đang tìm kiếm. Cảm ơn. –

14

Không chắc chắn nếu điều này hữu ích. Tôi đoán bạn đang chạy V1. Cách tiếp cận V2 này không ném và in kết quả:

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

Bạn đang đúng, tôi đang sử dụng điện shell v1. –

0

Tôi gặp vấn đề tương tự. Cách đơn giản nhất để có được đầu ra khi pipe.Invoke() ném một ngoại lệ là sử dụng Invoke(IEnumerable input, IList output)

Ví dụ cho thấy làm thế nào để có được tất cả đầu ra, lỗi, waning vv trong thứ tự đúng

PowerShell script

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}"); 
}             
} 
Các vấn đề liên quan