VBScriptの限界を突破せよ:PowerShellと.NETを操る「禁断の拡張術」
VBScriptを愛する皆さん、こんにちは。
自動化の現場でVBScriptを使っていると、一度はこう思ったことはありませんか?
「もっと複雑なデータ処理がしたい」「Windows APIを叩きたい」「モダンな暗号化やJSON解析を、余計なライブラリなしでやりたい」と。
VBScriptはシンプルですが、そのままだと「非力な若手」です。しかし、「強力な外部の専門家(PowerShellと.NET)」を呼び出すことさえ覚えれば、一気に「百人力のチーフアーキテクト」へと変貌します。
今日は、VBScriptからPowerShellの`Add-Type`を呼び出し、C#コードをその場でコンパイルして実行するという、まさに「禁断の拡張術」を伝授します。
—
なぜこの手法が必要なのか?
VBScript単体では、メモリ上のバイナリ操作や、最新の暗号化アルゴリズムの実装は極めて困難です。しかし、Windowsには標準で`.NET Framework`という巨大なツールボックスが備わっています。
PowerShellの`Add-Type`機能を使えば、テキストとして書かれたC#コードをメモリ上でコンパイルし、その場でDLL化してメモリにロードできます。これを利用すれば、VBScriptは「司令塔」に徹し、重たい処理はC#の高速な実行エンジンに丸投げできるのです。
—
実装の全体像:司令塔(VBScript)から実行部(C#)へ
まずはコードを見てください。これが、VBScriptからC#を呼び出すためのテンプレートです。
‘ C#コードを文字列として定義(ここがコンパイルされます)
Dim csCode
csCode = “using System;” & _
“public class Calculator {” & _
” public static string Add(int a, int b) {” & _
” return “”計算結果は: “” + (a + b).ToString();” & _
” }” & _
“}”
‘ PowerShellコマンドの組み立て
‘ -NoProfile: 起動時間を短縮
‘ -Command: Add-TypeでC#をロードし、そのメソッドを実行
Dim psCmd
psCmd = “powershell -NoProfile -Command ” & _
“””Add-Type -TypeDefinition ‘” & csCode & “‘; [Calculator]::Add(10, 20)”””
‘ 実行と結果の取得
Dim shell, result
Set shell = CreateObject(“WScript.Shell”)
‘ Execを使って標準出力をキャプチャする(ここがポイント!)
Set result = shell.Exec(psCmd)
WScript.Echo result.StdOut.ReadAll
Set result = Nothing
Set shell = Nothing
—
ここがプロの勘所:コード解説
1. `WScript.Shell` の `Exec` メソッドを使う理由
よく使われる `Run` メソッドは、外部プログラムを起動するだけで「結果」を拾えません。`Exec` メソッドを使うことで、PowerShellの標準出力(`StdOut`)をそのままVBScript側へストリームとして引き渡すことができます。
2. `Add-Type` は「メモリ上の錬金術」
PowerShellの `Add-Type` は、物理ファイルを作成せずにメモリ内でコンパイルを行います。つまり、ディスクにゴミを残さず、高速に処理が完結するという、運用上の大きなメリットがあります。
3. 陥りやすいエラー:クォーテーションの迷宮
VBScript内でPowerShellのコマンド文字列を作る際、クォーテーション(`”`)が二重三重に重なりがちです。
- VBScriptの文字列内では `”` は `””` と書く
- PowerShell側の文字列引数にも `”` が必要
この「クォーテーションの入れ子構造」を制する者が、VBScriptの自動化を制します。
—
読者の皆さんへ:この技術の「先」にあるもの
この手法をマスターすると、以下のようなことが可能になります。
- REST APIの高度な呼び出し: VBScript標準のXMLHTTPでは扱いにくい、複雑な認証やヘッダーが必要なAPIも、C#の `HttpClient` を使えば一撃です。
- バイナリファイルの高速処理: 数ギガバイトのログファイルを、C#の `StreamReader` を使って高速フィルタリングして結果だけ返す。
- Windows APIの直接呼び出し: `DllImport` を使って、VBScriptからは不可能なOS深層の制御を行う。
最後に
「VBScriptは古い」という意見を聞くこともありますが、Windows環境においてこれほど手軽に、かつ強力にOSを制御できる言語は他にありません。
今回の手法は、VBScriptの「軽快さ」と.NETの「重厚さ」を繋ぐブリッジです。まずは上のコードをコピーして、`10 + 20` の計算結果が画面に表示される感動を味わってください。
ここをクリアすれば、あなたの自動化ツールは「単なるスクリプト」から「堅牢なシステム」へと進化します。応援していますよ!
