Pipeline.Invokeがスローした後、C#でPowershell出力をキャプチャする
-
22-07-2019 - |
質問
C#アプリケーションからPowershellテストスクリプトを実行しています。 pipe.Invoke()が例外をスローする原因となる不正なコマンドレットが原因で、スクリプトが失敗する可能性があります。
例外について必要なすべての情報をキャプチャできますが、その時点までのスクリプトの出力を表示できるようにしたいと思います。例外がスローされると結果が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?
}
解決 2
私が最終的に使用したソリューションは、独自のPSHostを実装してPowerShellの出力を処理することでした。これに関する最初の情報は、 http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx 「カスタムPSホストの構築」でセクション。
私の場合、カスタムPSHostRawUserInterfaceも使用する必要がありました。
これまでに行われた作業の概要を簡単に説明します。実際に実装した関数のみをリストしましたが、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
}
他のヒント
これが役立つかどうかはわかりません。 V1を実行していると思います。このV2アプローチは結果をスローして出力しません:
Hello World
67 errors
string script = @"
'Hello World'
ps | % {
これが役立つかどうかはわかりません。 V1を実行していると思います。このV2アプローチは結果をスローして出力しません:
<*>.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);
}
同じ問題があります。 pipe.Invoke()が例外をスローしたときに出力を取得する最も簡単な方法は、 Invoke(IEnumerable入力、IList出力)
すべての出力、エラー、ワーニングなどを正しい順序で取得する方法の例
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(<*>quot;ERROR: {err}");
};
psInstance.Streams.Warning.DataAdded += (sender, args) =>
{
WarningRecord warning = ((PSDataCollection<WarningRecord>)sender)[args.Index];
RunLog.Add(<*>quot;WARNING: {warning}");
};
... etc ...
var result = new PSDataCollection<PSObject>();
result.DataAdded += (sender, args) =>
{
PSObject output = ((PSDataCollection<PSObject>)sender)[args.Index];
RunLog.Add(<*>quot;OUTPUT: {output}");
};
try
{
psInstance.Invoke(null, result);
}
catch(Exception ex)
{
RunLog.Add(<*>quot;EXCEPTION: {ex.Message}");
}
}