現場のエンジニアへ:タスクスケジューラにおける「カレントディレクトリの罠」を完全に制圧する
VBScriptは、もはや「過去の遺物」などではない。WindowsがOSとして存在し続ける限り、APIの直下で軽快に動作するこの言語は、最も信頼できるインフラ自動化の武器だ。
しかし、多くの管理者がタスクスケジューラを用いた自動実行で壁に突き当たる。「なぜ、手動実行では動くのに、タスクスケジューラだとファイルが見つからないのか?」 という嘆きだ。これは言語の不備ではなく、ホスト環境(WSH)とタスクスケジューラのライフサイクルに対する理解不足に起因する。
今日は、プロとしてこの問題を根絶するための「カレントディレクトリ補正」の極致を伝授する。
—
1. なぜ「相対パス」はタスクスケジューラで裏切るのか
タスクスケジューラがスクリプトをキックする際、プロセスは通常 `C:\Windows\System32` などのシステムディレクトリをカレントとして起動する。スクリプト内で `.\config.ini` のように相対パスを指定すれば、当然のことながらシステムフォルダ内を探しに行き、実行時エラーを吐く。
これを回避するために「絶対パス」をハードコードするのは、移植性を殺す愚行だ。我々が書くべきは、「スクリプト自身の格納場所を動的に特定し、カレントをそこに固定する」 ロジックである。
—
2. カレントディレクトリ補正の極限ロジック
以下は、実行開始時に即座にカレントディレクトリを自身のフォルダに強制固定するテンプレートだ。これをスクリプトの冒頭に配置することで、環境の不整合を完全に排除できる。
‘ — 実行環境最適化モジュール —
Option Explicit
‘ メモリリークを許さない。オブジェクト参照の明示的解放を徹底する。
Dim objFSO, objShell
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objShell = CreateObject(“WScript.Shell”)
‘ カレントディレクトリをスクリプト自身の場所へ強制遷移
‘ WScript.ScriptFullName はスクリプトの絶対パスを返す
objShell.CurrentDirectory = objFSO.GetParentFolderName(WScript.ScriptFullName)
‘ ここから先の相対パスは、すべてスクリプトと同じ階層を起点とする
‘ 例: Set objFile = objFSO.OpenTextFile(“.\settings.json”, 1)
‘ ———————————————————
‘ メイン処理をここに記述
‘ ———————————————————
‘ 終了処理:メモリ最適化のための明示的解放
‘ VBScriptのガベージコレクションを待つ必要はない。即時解放がプロの嗜み。
Set objFSO = Nothing
Set objShell = Nothing
WScript.Quit 0
—
3. レガシー環境を支える「WScript.Shell」の真実
タスクスケジューラでの実行時に考慮すべきは、ディレクトリだけではない。「環境変数」だ。GUIログインセッションとは異なり、タスクスケジューラは独自の環境変数を保持する。
もしスクリプトが特定のユーザー環境変数やパスに依存しているなら、以下のようにWSH経由で環境変数を拡張・取得するのが定石だ。
‘ 環境変数 ‘APP_HOME’ を取得し、なければデフォルト値を設定する防衛的コーディング
Dim strAppHome
strAppHome = objShell.ExpandEnvironmentStrings(“%APP_HOME%”)
If strAppHome = “%APP_HOME%” Then
‘ 環境変数が未定義の場合のフォールバック
strAppHome = objFSO.GetParentFolderName(WScript.ScriptFullName)
End If
—
4. プロのアーキテクトが語る「安定運用のための鉄則」
1. パスの結合には必ず `BuildPath` を使え
`”\”` の有無でバグを埋め込むのは素人だ。`objFSO.BuildPath(folder, file)` を使用すれば、パスのセパレータ問題を意識する必要は一切なくなる。
2. ログ出力は常に絶対パスで
エラーが発生した際、スクリプトがどこで死んだかを確認できないのは致命的だ。ログファイルへのパスは、カレントディレクトリ補正後のパスを使ってフルパスで生成せよ。
3. タスクスケジューラ側の設定:「作業フォルダー」を過信するな
タスクスケジューラのプロパティに「開始(オプション)」という項目があるが、これに頼るな。構成変更や移行時に設定漏れが必ず発生する。「スクリプト自身が自分の場所を知っている」状態こそが、メンテナンスフリーのアーキテクチャである。
—
結論
VBScriptは、正しく扱えば極めて堅牢な自動化ツールだ。タスクスケジューラ特有の挙動を「バグ」と捉えるのではなく、OSの特性として理解し、上記のような「自己完結型のコード」を実装する。
これが、レガシーシステムを10年先まで現役として使い倒すための、エンジニアとしての矜持である。さあ、今すぐコードを書き換え、不安定な実行環境を過去のものにせよ。
