更新: 以下でヒットした手法は、任意の GUI アクションに適していますが、私の目的 (クリーンアップされた形式で PowerShell 出力を表示する) では、カスタム PSHost、PSHostUserInterface、および PSHostRawUserInterface を実装する方が簡単であることがわかりました。サイド側はよりシンプルなままです (特注の出力 API ではなく、使い慣れた Write-Output、Write-Host、Write-Error などを使用します。これにより、ホストの外部でもスクリプトを実行する場合に備えて、スクリプトが柔軟に保たれます) . 良い例については、https://msdn.microsoft.com/en-us/library/ee706570%28v=vs.85%29.aspxを参照してください。
コマンドレットは間違ったアプローチであることが判明しました。その方法は、「SessionState」API を介して GUI オブジェクト インスタンスを PowerShell に公開し、PowerShell コードがそれらを直接使用できるようにすることです。方法は次のとおりです。
適切な名前空間を導入します。
using System.Management.Automation;
using System.Management.Automation.Runspaces;
次に、実行空間を作成し、GUI オブジェクト インスタンスを PowerShell 変数として挿入します。(ここでは、Messages コレクションを公開するビューモデルを渡していますが、実際にはより適切にレイヤー化することをお勧めします。) 実行空間を作成するときに、次のように InitialSessionState のいずれかを使用できます。
var iss = InitialSessionState.CreateDefault();
iss.Variables.Add(new SessionStateVariableEntry("thing", this.DataContext, "it's the data context"));
using (Runspace runspace = RunspaceFactory.CreateRunspace(iss))
{
runspace.ThreadOptions = PSThreadOptions.UseCurrentThread;
runspace.Open();
using (PowerShell ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddScript(@"$thing.Messages.Add('in which PowerShell can make stuff happen on the GUI via InitialSessionState')");
ps.Invoke();
}
runspace.Close();
}
または、Runspace.SessionStateProxy.SetVariable(name, object) を使用して、Runspace を作成して開いた後にオブジェクト インスタンスを挿入できます。そのコードは同じですが、InitialSessionState を挿入する必要はありません。
Doug Finkeは、私が見つけた彼のスクリーンキャストからテクニックを学んだので、これの功績を認められています。
http://www.dougfinke.com/blog/index.php/2009/09/02/how-to-host-powershell-in-a-wpf-application/