VBScriptをタスクスケジューラで「確実に」動かす:カレントディレクトリの罠と解法
業務自動化の現場で、VBScriptは依然として強力な武器だ。インストール不要、軽量、そしてWindows環境に深く根ざしている。しかし、多くのエンジニアがタスクスケジューラに登録した瞬間に「なぜかファイルが見つからない」「ログがどこにも出力されない」という壁に突き当たる。
これは、VBScriptが悪いのではない。タスクスケジューラという「閉じた異世界」の挙動を理解していない設計が悪いのだ。
今日は、タスクスケジューラ運用で最も頻発する「カレントディレクトリの不一致」を完全に制圧し、プロダクション環境で耐えうる堅牢なスクリプト設計を伝授する。
—
1. なぜタスクスケジューラでパスが迷子になるのか
手動実行時、カレントディレクトリ(`Current Directory`)はスクリプトが存在するフォルダを指すことが一般的だ。しかし、タスクスケジューラから実行されると、カレントディレクトリは多くの場合 `C:\Windows\System32` に固定される。
この状態で相対パス(例: `.\config.ini`)を指定すれば、システムフォルダ内を探索しに行き、当然のごとくエラーで爆死する。これが自動化の失敗パターンの9割を占める。
解決の鉄則:パスを「固定」するな、「生成」せよ
スクリプト自身が「自分がどこにいるか」を認識し、その場所を起点とした絶対パスを動的に生成する設計こそが、プロのアーキテクチャだ。
—
2. 堅牢な実行環境を構築するプロダクションコード
以下のコードは、カレントディレクトリの依存関係を排除し、ログ出力まで完結させるためのテンプレートだ。これをそのままコピペして、`WScript.ScriptFullName` の魔法を理解してほしい。
‘ ==============================================================================
‘ 堅牢な自動化スクリプトの雛形
‘ 作成者: チーフアーキテクト
‘ 特徴: 実行パスの自動補正、相対パス依存からの脱却
‘ ==============================================================================
Option Explicit
Dim objFSO, objShell
Dim strScriptPath, strBaseDir
Dim strLogPath
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objShell = CreateObject(“WScript.Shell”)
‘ 1. スクリプトのフルパスからベースディレクトリ(カレント)を動的に抽出
‘ WScript.ScriptFullNameは、タスクスケジューラ経由でも確実に自身の場所を指す
strScriptPath = WScript.ScriptFullName
strBaseDir = objFSO.GetParentFolderName(strScriptPath)
‘ 2. 外部リソース(設定ファイルやログ)へのパスを絶対パスで結合
strLogPath = objFSO.BuildPath(strBaseDir, “execution.log”)
‘ 3. ロジック実行前にカレントディレクトリをスクリプトの場所に強制変更
‘ これにより、外部ライブラリ読み込みや相対パス指定の記述ミスを防ぐ
objShell.CurrentDirectory = strBaseDir
‘ — ここからメイン処理 —
WriteLog “タスク開始: ” & Now
‘ 例: 設定ファイルを読み込む場合
‘ Set configFile = objFSO.OpenTextFile(objFSO.BuildPath(strBaseDir, “config.ini”))
‘ 処理終了
WriteLog “タスク終了: ” & Now
‘ — 終了処理 —
Set objFSO = Nothing
Set objShell = Nothing
‘ ログ出力用プロシージャ
Sub WriteLog(msg)
Dim objLog
Set objLog = objFSO.OpenTextFile(strLogPath, 8, True) ‘ 8: ForAppending
objLog.WriteLine “[” & Now & “] ” & msg
objLog.Close
Set objLog = Nothing
End Sub
—
3. 運用・設計のプロフェッショナル・アドバイス
① カレントディレクトリの強制変更(`objShell.CurrentDirectory`)
上記のコードで最も重要なのは `objShell.CurrentDirectory = strBaseDir` の行だ。これを入れることで、スクリプト内で `.\file.txt` と記述しても、実行環境に左右されず、常にスクリプトと同じフォルダを見に行くようになる。
② タスクスケジューラの「開始」オプション
タスクスケジューラのプロパティにある「開始(オプション)」フィールドを空欄にするエンジニアが多いが、必ず「スクリプトが保存されているディレクトリ」を指定すること。
これは二重の防波堤となる。スクリプト側でパスを補正し、スケジューラ側でも環境を整える。これが壊れないシステムの流儀だ。
③ データベース連携時の注意点
DB接続文字列(DSNや接続先ファイルパス)に相対パスを使っているなら、今すぐ絶対パスに書き換えろ。特にAccessの `.accdb` ファイルなどを扱う場合、スケジューラ環境下ではドライブレターの認識すら怪しくなることがある。`UNCパス(\\Server\Share\…)` を検討する準備も常に怠らないこと。
—
最後に:なぜ「動くもの」ではなく「壊れないもの」を作るのか
コードが動くのは当たり前だ。しかし、タスクスケジューラに委ねる自動化プロセスは、「誰にも見られない場所で、静かに失敗する」リスクを孕んでいる。
今日伝授した「パスの動的生成」と「カレントディレクトリの制御」は、自動化の安定性を飛躍的に高める。この設計パターンを標準としてインストールすることで、あなたの開発するツールは、深夜のサーバー環境でも安心して放置できる「無言の優秀な部下」へと進化するはずだ。
さあ、コードをリファクタリングし、環境依存という名の不確実性を排除せよ。
