VBScriptを「最強の糊」に変える:StdIn/StdOutによる異言語連携の極意
世間では「VBScriptはレガシーだ」と揶揄される。しかし、Windows環境において、これほど低負荷で、インストール不要で、OSの深部まで即座にアクセスできる言語は他にない。
多くのエンジニアが陥る過ちは、VBScriptを単なる「ファイル操作ツール」として使うことだ。そうではない。VBScriptの真価は、「軽量なインターフェース」として他言語の強力な処理能力を指揮する「司令塔」になることにある。
今日は、VBScriptとPython/Node.jsをパイプラインで直結し、堅牢なデータパイプラインを構築するアーキテクチャを伝授する。
—
なぜ「ファイル書き出し」を捨て、「標準入出力」を選ぶのか
多くの初心者は、プログラム間通信に「中間ファイル(JSONやCSV)」を使う。だが、大規模な自動化ではこれは悪手だ。
- I/Oのボトルネック: ディスクへの書き込みはネットワーク通信よりも遅い。
- 競合リスク: ファイルロックや書き込みタイミングの齟齬は、生産現場で最も追跡困難なバグを生む。
- ライフサイクルの管理: 不要になった中間ファイルの削除漏れは、サーバーのストレージを確実に圧迫する。
`StdIn` (標準入力) と `StdOut` (標準出力) を用いたパイプライン通信は、メモリ上のストリームで完結する。高速、かつ揮発的。これがプロの選択だ。
—
堅牢な実装:VBScriptを司令塔にする
VBScript側でPythonのプロセスを起動し、ストリームを掴む。ここで重要なのは、「ブロッキング処理」を正しく制御することだ。
VBScript 実装例 (controller.vbs)
‘ CScript環境で実行すること。WScriptではStdOutが使えない。
Option Explicit
Dim objShell, objExec, strCommand, strInput
Set objShell = CreateObject(“WScript.Shell”)
‘ Pythonスクリプトを呼び出し、StdIn/StdOutをパイプラインで繋ぐ
strCommand = “python worker.py”
Set objExec = objShell.Exec(strCommand)
‘ Pythonへのデータ送信
objExec.StdIn.WriteLine “TASK_START:DATA_PROCESS_001”
objExec.StdIn.Close ‘ 送信終了を明示する(重要)
‘ Pythonからの応答をリアルタイムで取得
Do While objExec.Status = 0
WScript.Sleep 100
Loop
If Not objExec.StdOut.AtEndOfStream Then
WScript.Echo “Result from Python: ” & objExec.StdOut.ReadAll
End If
Set objExec = Nothing
Set objShell = Nothing
—
Python側の作法:ストリームを止めない工夫
Python側は、VBScriptからの入力を待機し、結果を標準出力に流す。ここで重要なのは、`sys.stdout.flush()` を忘れないことだ。バッファリングが効きすぎると、VBScript側でデッドロックが発生する。
Python 実装例 (worker.py)
import sys
def main():
# VBScriptからの入力を読み取り
input_data = sys.stdin.readline().strip()
if “TASK_START” in input_data:
# ここに重い処理(外部API連携やDBクエリなど)を書く
result = f”Processed: {input_data.split(‘:’)[1]}”
# 結果を標準出力へ。flush必須。
print(result)
sys.stdout.flush()
if __name__ == “__main__”:
main()
—
現場で生き残るための「鉄則」
このアーキテクチャをプロダクション環境に投入する際、以下の3点だけは死守せよ。
1. エラーハンドリングの分離
VBScriptの `StdErr` を見逃すな。Python側で例外が発生した場合、`StdErr` に出力させ、VBScript側でそれを拾い上げてログファイルに転送する設計にすること。これだけで、原因不明の停止を劇的に減らせる。
2. 文字コードの罠
Windowsの `CScript` はデフォルトで `Shift-JIS` を扱うことが多い。Pythonは `UTF-8` が標準だ。パイプラインの途中で文字化けが発生する場合、環境変数 `PYTHONIOENCODING=utf-8` をセットしてプロセスを起動する等の対策が必要になる。
3. プロセス監視の徹底
`objShell.Exec` は非同期実行だが、親プロセス(VBScript)が終了しても子プロセスがゾンビ化することがある。確実に終了させるために、`On Error Resume Next` と組み合わせた終了処理(Terminate)を必ず実装すること。
—
結論:技術は「目的」のためにある
VBScriptを単体で頑張らせる時代は終わった。
しかし、OSのネイティブな挙動を理解し、パイプラインという「枯れた技術」を再定義することで、PythonやNode.jsの高度なライブラリ群を、Windowsの業務自動化ツールとしてシームレスに組み込めるようになる。
この記事を読んだ君なら、もう中間ファイルに頼るような非効率なコードは書かないはずだ。
システムを止めない、美しく、そして速い自動化基盤を構築してほしい。それができるのが、真の自動化エンジニアだ。
