VBScriptを極める:ADODB.Streamによるバイナリ操作の深淵
VBScriptは「レガシー」という言葉で片付けられることが多い。だが、Windowsの心臓部(WSH)に直結し、追加のランタイムを一切必要とせずにOSの深層を叩けるこの言語は、正しく扱えば最強の武器となる。
特に、テキストベースの処理を超え、バイナリファイルを直接操作する術を習得することは、システム管理者やレガシーアーキテクトにとっての「ラスト・リゾート」だ。今回は、`ADODB.Stream` を駆使し、バイナリの海を泳ぐための極意を伝授する。
—
1. なぜ ADODB.Stream なのか
VBScriptでバイナリを扱う際、FileSystemObject (FSO) は無力だ。FSOはテキストストリームを前提としており、Nullバイトや特殊な制御コードを読み込むと文字列としての整合性を破壊する。
ここで登場するのが `ADODB.Stream` である。本来はデータベース連携用のコンポーネントだが、`Type = 1 (adTypeBinary)` を指定することで、メモリ上に生のバイト列をロードできる。これは、Windows APIを直接叩くのが困難なVBScriptにおいて、唯一無二のバイナリインターフェースである。
—
2. バイナリ・パースの実装コード
以下のコードは、画像やZIPファイルのヘッダー(マジックナンバー)を読み取り、検証するプロフェッショナル・テンプレートだ。
‘ ADODB.Streamを用いたバイナリ解析テンプレート
Option Explicit
Const adTypeBinary = 1
Function GetBinaryHeader(strFilePath, lngLength)
Dim objStream
Set objStream = CreateObject(“ADODB.Stream”)
‘ ストリームの初期化
objStream.Type = adTypeBinary
objStream.Open
objStream.LoadFromFile strFilePath
‘ 必要なバイト数だけ読み出し
‘ Readメソッドは、読み込み位置(Position)を自動的に進める
GetBinaryHeader = objStream.Read(lngLength)
‘ 厳密なメモリ解放
objStream.Close
Set objStream = Nothing
End Function
‘ 16進数ダンプへの変換関数
Function ToHexString(binData)
Dim i, byteVal, hexStr
hexStr = “”
For i = 1 To LenB(binData)
‘ AscBはバイト値を返し、Hexで16進数へ変換
byteVal = AscB(MidB(binData, i, 1))
hexStr = hexStr & Right(“0″ & Hex(byteVal), 2) & ” ”
Next
ToHexString = Trim(hexStr)
End Function
‘ — 実行例 —
Dim binaryData, filePath
filePath = “C:\temp\sample.zip”
binaryData = GetBinaryHeader(filePath, 4)
‘ ZIPファイルのシグネチャ (50 4B 03 04) を検証
WScript.Echo “Header Signature: ” & ToHexString(binaryData)
—
3. シニアエンジニアが意識すべき「メモリの重み」
VBScriptのメモリ管理は参照カウンタ方式だ。しかし、COMオブジェクト(ADODB.Streamなど)はランタイムの寿命とは別に、明示的に `Close` して `Nothing` を代入しなければ、GC(ガベージコレクション)に頼り切ることになる。
- 大容量ファイルの読み込み回避: `ADODB.Stream` に数GBのファイルを読み込ませてはならない。WSH環境でのメモリオーバーフローはプロセスを即座にクラッシュさせる。必要なヘッダー分だけを `Read` するか、ストリームを逐次移動(`Position` プロパティ)させて解析せよ。
- バイナリ型の扱い: VBScriptの変数に代入されたバイナリデータは、内部的には `Variant` 型の `Byte Array` として格納される。これを加工しようとするとパフォーマンスが激減するため、可能な限り `MidB` や `AscB` といった低レベルなバイト操作関数に限定すること。
—
4. 現場で生き残るための高度な知見
1. 文字コードの罠に触れない
バイナリモード (`adTypeBinary`) で開いている限り、`Charset` プロパティは無視される。しかし、誤って `adTypeBinary` 以外のモードと混同すると、Windowsのコードページ変換が走り、バイナリが破壊される。必ず `Open` 直後に設定を確定させること。
2. ファイルロックの防衛
`LoadFromFile` は排他制御を行う。解析中に他プロセスが書き込みを行う可能性がある場合、読み取り専用ストリームであっても `On Error Resume Next` で囲み、ハンドル取得失敗時のリトライ処理(指数バックオフなど)を実装するのが、高可用性システムへの第一歩だ。
3. バイナリとテキストの橋渡し
もし読み込んだバイナリを文字列として扱いたい場合は、`ADODB.Stream` を一度 `adTypeBinary` で開き、`Read` したデータを `ADODB.Recordset` の `AppendChunk` 等を経由して変換する手法がある。しかし、基本的にはバイナリはバイナリのまま、`AscB` で検証するのが最も安全で高速である。
—
結びに代えて
VBScriptは、今なおレガシーシステムの裏側で、OSの権限を背景に無言で働き続けている。バイナリを直接パースできるエンジニアは、たとえ仕様書が存在しないブラックボックス化したファイル形式であっても、その中身を暴き出し、システム間の連携を強固にすることができる。
この技術は単なる古い手法ではない。「OSの標準機能だけでどこまで到達できるか」という技術的極致への挑戦である。皆さんの現場の自動化が、一歩先へ進むことを願っている。
