2009-08-05 6 views
11

나는 C# 응용 프로그램에서 Powershell 테스트 스크립트를 실행하고 있습니다. 스크립트는 잘못된 cmdlet으로 인해 실패 할 수 있으며 이로 인해 pipe.Invoke()가 예외를 throw합니다.Pipeline.Invoke throws 후 C#에서 Powershell 출력 캡처

예외에 대해 필요한 모든 정보를 캡처 할 수 있지만 그 시점까지 스크립트 출력을 표시 할 수 있기를 바랍니다. 예외가 throw 될 때 결과가 null 인 것으로 보이기 때문에 나는 운이 없었습니다.

내가 누락 된 자료가 있습니까? 감사!

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

답변

8

이 솔루션은 PowerShell에서의 출력을 처리하기 위해 우리 자신의 PSHost을 구현하는 것이 었습니다. 이에 대한 초기 정보는 "사용자 지정 PS 호스트 구축"절의 http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx에서 가져 왔습니다.

제 경우에는 사용자 지정 PSHostRawUserInterface도 사용해야합니다.

다음은 수행 된 작업에 대한 간략한 개요입니다. 나는 실제로 실제로 구현 된 함수를 나열했지만, 많은 것은 단지 새로운 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

좋은 물건, 내가 찾고 있었던 정확하게 것. 감사. –

14

도움이 될지 확실하지 않습니다. 나는 당신이 V1을 운영하고 있다고 추측합니다. 이 V2 접근 던지고 결과를 출력하지 않습니다 내가 사용 결국

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

당신은 올바른, 내가 사용하는 전원 셸 v1. –

0

나는 동일한 문제가 있습니다. pipe.Invoke()는 예외가 올바른 순서 등 해지는 모든 출력 오차를 얻는 방법 Invoke(IEnumerable input, IList output)

예제 사용 보여줍니다 발생 때 가장 쉬운 방법은 출력을 얻기 위해

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}"); 
}             
} 
관련 문제