PowerShell で .NET と親しくなるために

時間もネタもないまま仕事に没頭していましたので、唐突に殴り書きです。

PowerShell .NET Framework 上で動いているので、.NET と親和性が高いようになっています。結構な量のコマンドレットはあるのですが、それでも特定の事柄のために .NET の機能を直接呼び出すことで簡単に解決できることもあります。

特定のアセンブリPowerShell に読み込ませるには、Add-Type コマンドを使用します。たとえば、System.Windows.Forms.dll にある MessageBox クラスを使用してメッセージボックスを表示するには、

# System.Windows.Forms.dll を読み込む
PS > Add-Type -Assembly System.Windows.Forms

# MessageBox クラスの Show を呼び出す
PS > [Windows.Forms.MessageBox]::Show("選択してください", "こんにちは", "YesNoCancel")
No

こんなかんじになります。クラス名を指定するときはネームスペースの先頭の System だけは省略することができます。[Windows.Forms.MessageBox] は [System.Windows.Forms.MessageBox] と書いても一緒です。
この例のように、PowerShell から enum を与える場合、その名前を指定することで自動的に Enum.Parse() が呼び出されて .NET 側には enum が渡ります。もちろん、Enum 型を指定して [Windows.Forms.MessageBoxButtons]::YesNoCancel と記述してもかまいません。
メソッドについて調べたいときは、メソッド名だけを指定すればメソッドの情報が手に入ります。

PS > [Windows.Forms.MessageBox]::Show
MemberType           Method
OverloadDefinitions  { ... }
TypeNameOfValue      PSMethod
Value                static System.Windows...
Name                 Show
IsInstance           True

# オーバーロードの一覧を表示
PS > [Windows.Forms.MessageBox]::Show.OverloadDefinitions

新しくオブジェクトを作成するには、New-Object コマンドを使います。

# -Property オプションでオブジェクトイニシャライザっぽく書けます
PS > $form1 = New-Object System.Windows.Forms.Form -Property @{
    Text = "Form1";
    Size = New-Object System.Drawing.Size(400, 300);
}

# delegate の作成はスクリプトブロックを渡すだけです
PS > $form1.add_DoubleClick({
    param($sender, $e);

    # ダブルクリックすると OK と表示して終了する
    [Windows.Forms.MessageBox]::Show("ok");
    $sender.Close();
})

# WinForms のアプリケーションのメッセージ処理を開始する
PS > [Windows.Forms.Application]::Run($form1);

型を指定するの方法を使って型パラメータを引数にもできます。

# C# で言うところの List<int> を作成する
PS > $list = New-Object System.Collections.Generic.List[int]

ちょーっと殴り書きすぎました。ごめんなさい。