VBScriptを極める:レジストリとFSOを用いた「擬似IPC」によるプロセス間連携の奥義
VBScriptは、現代のモダンな言語から見れば「化石」のように見えるかもしれない。しかし、Windows環境下で外部依存なしに、極めて軽量かつ即座に業務自動化を実現するツールとして、これに勝るものは存在しない。
多くのエンジニアが陥る罠は、複数のVBScriptプロセスを立ち上げた際、それらを「孤立した島」として扱うことだ。しかし、真の自動化アーキテクトは、プロセス間に「通信路」を構築する。今回は、レジストリとFileSystemObject (FSO)を組み合わせた、堅牢かつ高速な「擬似プロセス間通信(IPC)」の設計思想を伝授する。
なぜ「ファイル書き出し」だけでは不十分なのか
単にテキストファイルを介してメッセージをやり取りしようとすると、必ず以下の壁に突き当たる。
1. 競合(Race Condition): 読み込みと書き込みが同時に発生した瞬間に発生するI/Oエラー。
2. 遅延(Latency): ディスクへの書き込み完了を待機するオーバーヘッド。
3. 状態の不整合: プロセスが異常終了した際に残る「ゴミファイル」の処理。
これらを解決するための最適解が、「排他ロックファイル」による同期と「高速な状態保持」としてのレジストリの使い分けだ。
—
堅牢なIPC設計のアーキテクチャ
設計の肝は、「通信のデータ本体はファイルに置くが、状態の同期(ロック・通知)はレジストリまたはロック用ダミーファイルで行う」という点だ。
1. ロックの仕組み
FSOの `OpenTextFile` で排他制御を試みる。ファイルが開ければロック獲得、開けなければ「他プロセスが使用中」と判断して待機(ポーリング)する。
2. データ転送
レジストリ(`WScript.Shell`の`RegWrite`)は設定値の保持には向くが、頻繁な書き換えはOSのハイブを肥大化させるリスクがある。動的なメッセージ転送は「一時ファイル」を使い、ファイルパスの受け渡しにレジストリを用いるのが最も安定する。
—
実装:プロセス間通信クラス(プロダクション仕様)
このコードを共通ライブラリとして保存し、各スクリプトから呼び出すことを想定している。
‘ IPCManager.vbs – 堅牢なプロセス間通信の実装
Class IPCManager
Private fso, shell
Private m_LockFilePath
Public Sub Class_Initialize()
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set shell = CreateObject(“WScript.Shell”)
‘ 一時フォルダにロック用ファイルを指定
m_LockFilePath = fso.GetSpecialFolder(2) & “\vbs_ipc.lock”
End Sub
‘ 排他制御を伴うデータ書き込み
Public Sub SendMessage(message)
Do While Not TryLock()
WScript.Sleep 10 ‘ 10ms待機してリトライ
Loop
‘ データを書き込み
Dim ts
Set ts = fso.CreateTextFile(fso.GetSpecialFolder(2) & “\ipc_data.tmp”, True)
ts.Write message
ts.Close
‘ ロック解除
fso.DeleteFile m_LockFilePath
End Sub
Private Function TryLock()
On Error Resume Next
‘ ファイルを作成して排他ロックを試みる
fso.CreateTextFile(m_LockFilePath, False).Close
If Err.Number = 0 Then
TryLock = True
Else
TryLock = False
End If
On Error GoTo 0
End Function
End Class
‘ — 利用例 —
Dim ipc: Set ipc = New IPCManager
ipc.SendMessage “TASK_START:BatchJob_001”
—
運用のための「鉄の掟」
このコードを現場で使いこなすために、以下の3点を必ず遵守せよ。
1. 異常系ハンドリングの徹底
プロセスが途中でクラッシュした場合、`m_LockFilePath`(ロックファイル)が残ったままになる。これを防ぐため、メインスクリプトの冒頭では「古いロックファイルが一定時間以上放置されていないか」をチェックし、古い場合は強制削除する処理を組み込む必要がある。
2. ファイルシステムキャッシュを過信しない
FSOは便利だが、書き込み直後に別プロセスが読み込むと、OSのキャッシュにより古い内容を掴むことがある。書き込みの直後に `WScript.Sleep 50` 程度のバッファを置くことは、泥臭いが「バグを出さない」ための正攻法だ。
3. レジストリへの書き込み頻度を最小化
もしプロセス間で「現在時刻」や「進捗フラグ」を共有したい場合、それを頻繁にレジストリに書くのはNGだ。レジストリはあくまで「設定」や「プロセス識別子(PID)」の保存にとどめ、高速な通信は今回のようなファイルベースのIPCで行うこと。
結びに代えて
VBScriptは、現代のCI/CDパイプラインには載らないかもしれない。しかし、現場のPC一台で、サーバーを立てることなく、並列処理による業務効率化を即座に達成できる強力な武器だ。
「綺麗なアーキテクチャ」を求めるあまり過剰な設計に走るな。泥臭いロック制御の中にこそ、安定した自動化の命が宿る。このIPC実装を理解した貴方なら、もはやVBScriptで構築できない業務は存在しないはずだ。
さあ、コードを書いて、現場の非効率を焼き払おう。
