ログファイルをgrepした結果をOutlookでメール送信するサンプルスクリプト

ログファイルをgrepした結果をOutlookでメール送信するサンプルスクリプトをVBSで作成。
ポイントは以下の2点。
・Windowsでgrepをどのように実現するか
・メール本文にログファイル全文をどう書くか

Windowsでgrepする方法はfindstrコマンドで実現可能で、正規表現も検索文字列に指定できる。

しかしfindstrはVBSの関数ではないため、 CreateObject("WScript.Shell") してから Exec("%ComSpec% /c (コマンド)") しなければいけない。

2点目の問題と同じなのだが、Execでコマンド実行した結果が標準出力に出て、それを取得しようとしたときに出力サイズによっては問題が発生する。

標準出力に4KB(4096byte)以上出力しバッファがいっぱいになっている状態では、Exec.StdOutで読み込みを行おうとしてもデッドロックがかかってしまい、スクリプトが止まってしまう。

StdOut, StdErrストリームは、4KBのバッファを共有しています。また、WshScriptExecオブジェクトは、単にこのストリームを同期的に読み込む操作を行うだけです。
同期読み込み操作は、呼び出したスクリプトの読み込みと、子プロセスの書き込みに依存しています。これがデッドロック状態を起こしうるのです。
子プロセスのストリームを読み込むとき、子プロセスに依存した形になります。子プロセスがストリームに書き込むか、ストリームを閉じるまで、呼び出しは完了しません。
一方、子プロセスがストリームのバッファ(4KB)をいっぱいにしてしまうとき、親プロセスの読み込みに依存しています。
親プロセスがバッファから完全に読み込むか、ストリームを閉じるまで、子プロセスの書き込み操作は待ち状態に入って完了しません。
このようにして、スクリプトと子プロセスがお互いに読み書きを待つ状態に陥ると、デッドロック(フリーズ)が生じます。

引用:http://p2pquake.ddo.jp/mskb/archives/261

findstrの結果だけなら問題ないことも多いが、ログファイル全文となると簡単に4KBを超えてしまうので、 以下のようにEndOfStreamに到達するまで常にReadLineする必要がある。

ログファイルの内容自体は、テキストファイルなどの内容を標準出力に表示するコマンドtypeを使用している。

サンプルスクリプト

mail.vbs

-Windows