タスクスケジューラでバッチファイルが動かない原因は3つ。手動では動くのに(0x1)になるときの直し方

タスクスケジューラでバッチファイルが動かない原因は3つ。手動では動くのに(0x1)になるときの直し方
当サイトはアフィリエイト広告を利用しています。

ダブルクリックすれば動くバッチファイル(bat)が、タスクスケジューラに登録した途端に動かない。
「前回の実行結果」には (0x1) という見慣れない数字が残っている。

タスクスケジューラへの登録手順そのものは Windowsで決まった時刻に処理を自動で動かす方法 にまとめています。

この記事に出てくる用語
  • タスクスケジューラ … 決めた時刻や条件でプログラムを自動実行する、Windows付属の機能
  • バッチファイル(bat) … コマンドを上から順に実行するテキストファイル。拡張子は .bat
  • コマンドプロンプト … batを1行ずつ実行しているプログラム。batをダブルクリックすると出る黒いウィンドウ
  • カレントディレクトリ … プログラムが「いま自分がいる場所」として扱うフォルダ
  • 相対パス/絶対パス … 「data.txt」と今いる場所からの位置で書くのが相対パス、「C:\jobs\data.txt」と全部書くのが絶対パス

結論:「開始(オプション)」欄に、batのあるフォルダを入れる

手動では動くのに失敗するとき、疑うのはbatの中身ではありません。
タスクスケジューラは、何も設定しないと C:\Windows\System32 を現在地(カレントディレクトリ)にしてbatを動かします。
batの中の「data.txt」のようなファイル名だけの指定(相対パス)が見つからず、(0x1) で終わります。

できたはずのファイルが見当たらないときは、Windowsの検索では出てこない場所もあります。
コマンドで総当たりする打ち方があるはずのファイルが検索で出てこないときにあります。

最初に試すこと(ここが原因のことが多い)

  1. 先に、batが置いてあるフォルダのパス(場所の文字列)を調べておく。
    エクスプローラーで自分のbatを表示し、上部のアドレスバー
    (「PC > ローカルディスク (C:) > jobs」のように場所が並ぶ細長い欄)の、
    場所が並んでいる部分より右の空白をクリックします(Alt+D でも同じ)。
    「C:\jobs」のような文字に変わるので、Ctrl+C でコピーする。
    右クリックの「パスのコピー」は使わないでください。
    「”」が付いた形(”C:\jobs”)になり、手順4で使えません
  2. タスクスケジューラで該当タスクを右クリック →「プロパティ」
  3. 「操作」タブ → 操作を選んで「編集」
  4. 「開始(オプション)」欄に、1でコピーしたパスを貼り付ける(例: C:\jobs)。
    入れるのはフォルダまで。上の「プログラム/スクリプト」欄はファイル名(〜.bat)まで入っていますが、
    この欄はファイル名を含めず、「”」(ダブルクォーテーション)で囲みません
  5. OKで保存し、タスクを右クリック →「実行」
  6. 「前回の実行結果」を、F5キー(または画面右側の「最新の情報に更新」)で更新してから見る。
    更新しないと古い表示のままで、直ったかどうか分かりません。
    (0x0) になっていれば成功(batが作るはずのファイルができているかも見ると、より確実)。
    (0x1) のままならまだ直っていない。
    (0x41301) はまだ動いている途中なので、少し待って F5 を押し直してください

これで直らなければ、権限 → ログオン設定 の順に切り分けます。

系統中身典型的な症状
1. 実行される場所batが想定と違うフォルダを現在地にして動いている(0x1)。手動では動くのに失敗する
2. 権限管理者権限や実行ユーザーの違い書き込みなど特定の操作だけ失敗する
3. ログオン設定「ログオンしているかどうかにかかわらず」で実行環境が変わる画面が出ない・共有フォルダに届かない

手動では動くのに失敗する理由

「相対パスは、batファイルのある場所を基準に探される」と思われがちですが、実際の基準は「呼び出し元の現在地」です。
隣に置いた data.txt を表示するだけのbatで見ると、違いがはっきりします。

@echo off
type data.txt
動かし方結果
batのあるフォルダでダブルクリックdata.txt の中身が表示される(正常)
現在地を C:\Windows\System32 にして同じbatを呼ぶ(=タスクスケジューラの既定と同じ条件)「指定されたファイルが見つかりません」で失敗する

自分のbatがどこにいると思っているかは、次の2行を足すと batの隣の check_log.txt に残ります。

@echo off
echo CD  = %CD% >> "%~dp0check_log.txt"
echo BAT = %~dp0 >> "%~dp0check_log.txt"

タスクスケジューラの既定と同じ条件で動かすと、こう出ます(BATのフォルダ名は例です)。

CD  = C:\Windows\System32
BAT = C:\jobs\

相対パスの基準はCD(現在地)で、BAT(batの置き場所)とは別物です。
ダブルクリックで動くのは、エクスプローラーが「batのあるフォルダ」を現在地にして起動するからです。

切り分けの手順:コードを読んでから順に潰す

やみくもに設定を触る前に、「前回の実行結果」のコードを読みます。コードで原因の系統がかなり絞れます。

「前回の実行結果」の早見表

コード意味まず疑うこと
0x0正常終了タスク自体は成功している。「動いていないように見える」だけ(→系統3)
0x1batは起動したが、中の処理がエラーで終わったカレントディレクトリ(系統1)
0x2指定されたファイルが見つからない「プログラム/スクリプト」欄のパスの間違い。またはbat内のファイル参照
0x41301まだ実行中いつまでも終わらないなら、bat内の入力待ち(pause など)
0x41303まだ実行されていないトリガー(起動条件)が働いていない。開始日時と条件を見直す
0x8007010Bディレクトリ名が無効「開始(オプション)」を「”」で囲んでいる
0x800710E0要求が拒否されたbatではなくタスク側の設定(条件タブ・実行アカウント)を見直す

この欄には2種類の番号が混ざります。
0x0〜0x2 のような短いものは起動したプログラムが返した終了コード(0 が成功)であることが多く、
0x413… や 0x8007… で始まる長いものはタスクスケジューラ側の状態です。
(0x1) は「起動したが失敗した」なので、見直すのはトリガーではなくbatが動いた環境です。

切り分けの順序

  1. 表示を F5 で更新してコードを控え、上の早見表で系統を絞る
  2. (0x1) なら「開始(オプション)」を入れて、右クリック→「実行」で再テスト(系統1)
  3. 直らなければ、手動でも「管理者として実行」が要るbatかを確認する(系統2)
  4. それでも直らなければ、ログオン設定とbatの中身を突き合わせる(系統3)
  5. 絞れなければ、ログを仕込んで「どの行まで動いたか」を見る(後述)

系統1:実行される場所を直す。方法は2つ

方法A: タスク側で直す。「開始(オプション)」にbatのあるフォルダを入れます(冒頭の手順)。batには手を入れません。

方法B: bat側で直す。batの先頭(@echo off の直後)に次の1行を足します。

cd /d "%~dp0"

「%~dp0」は「このbat自身が置かれているフォルダ」、「cd /d」は「ドライブが違っても現在地をそこへ移す」という意味です。
この1行があれば、C:\Windows\System32 を現在地にして呼び出されても、batは自分の置き場所へ現在地を移してから続きを実行します。

状況選ぶ方法
自分のPCのタスク1本だけ。batを書き換えたくないA(開始欄に入力)
batを他のPCにも配る。ダブルクリックでも使う。今後もタスクを増やすB(cd /d “%~dp0″)
迷うB。batが自分で自分を守るので、タスク側の設定忘れがなくなる

切り分けの段階では、batに手を入れない方法Aで試すのが早いです。両方やっても衝突はしません。

系統1の例外:batを共有フォルダに置いている場合

bat自体を会社の共有フォルダに置いている場合は、追加の対処が要ります。
普段「Z:」のようなドライブ文字で開いているフォルダも同じで、
Z: は「\\サーバー名\共有名\…」に付けた省略形です。
Z: が指す先は、スタートボタンを押して「cmd」と入力してコマンドプロンプトを開き、
net use と打つと一覧で出ます。

そのままでは動かない理由は2つあります。
コマンドプロンプトは「\\サーバー名\…」形式を現在地にできない仕様で、
cd /d でも「開始(オプション)」でも移れません(この場合はWindowsフォルダで動き出します)。
もう1つは、Z: が自動実行のときには存在しないことがあること(理由は後半のネットワークドライブの節)。

対処は2点セットです。
bat側は、cd /d "%~dp0" の代わりに pushd "%~dp0" を先頭に書き、batの最後に popd を書く
(pushdは共有フォルダに一時的なドライブ文字を割り当ててから移動します)。
タスク側は、「プログラム/スクリプト」欄のbatの場所を、Z: ではなく「\\サーバー名\…」の形で書く。

共有フォルダは、タスクを動かすアカウントにアクセス権があることが前提です。
「かかわらず」を選ぶときは、パスワードを保存する設定にしてください
(保存しないと、タスクはネットワーク上の場所に届きません)。

系統2:権限を疑う。「最上位の特権」を安易に付けない

タスクのプロパティにある「最上位の特権で実行する」は、「管理者として実行」と同じ扱いでタスクを動かすチェックです。
(0x1) の対処としてこれを勧める情報も見かけますが、先に付けるものではありません。
判断基準は「そのbatを手動で動かすとき『管理者として実行』が必要か」の1つだけです。

手動での動かし方タスク側の設定
ダブルクリックで動くチェック不要。付けない
右クリック→「管理者として実行」でないと動かない(例: C:\Program Files 配下や C:\Windows 配下への書き込みがある)チェックする。ただしタスクに設定したアカウントに管理者権限があることが前提

「とりあえずチェック」を勧めない理由は3つあります。

  1. 原因が場所(系統1)なら直らないうえに、「権限は確認済み」という誤った消去が残り、切り分けが濁ります
  2. ネットワークドライブ(Z: など)を使うbatは、これを入れると逆に動かなくなることがあります
    (後述のネットワークドライブの節)
  3. 会社のPCでは管理者権限が付与されていないことが多く、その場合は入れても動きません。
    制限を回避する方法を探すのは方向が違います。
    管理者権限が必要な処理なら、情報システム部門に相談してください

タスクの「全般」タブにある実行ユーザーも権限の一部です。
別のアカウントやSYSTEMで登録されていると、そのユーザーの権限と環境で動きます。
「自分では開けるフォルダなのに失敗する」ときは、ここを確認してください。

系統3:ログオン設定を疑う

タスクの「全般」タブには「ユーザーがログオンしているときのみ実行する」と
「ユーザーがログオンしているかどうかにかかわらず実行する」の2択があります。
選び方はbatの中身で決まります。

batの中身選ぶ設定
画面に何かを表示する。ウィンドウを操作する(アプリの自動操作など)ログオンしているときのみ
ファイルのコピー・変換など、画面の要らない処理を無人で回したいかかわらず(ただし下の3点を確認)

「かかわらず」を選ぶと、実行環境が3つ変わります。

  1. 画面が出ません。
    黒いウィンドウは表示されず、正常に動いていても見えません(0x0 なら動いています)。
    bat内に pause のような入力待ちがあると、押す人がいないまま実行中(0x41301)のまま止まります
  2. ログオン中に実行してもネットワークドライブ(Z: など)が使えません
    (理由と対処は後半のネットワークドライブの節)
  3. 設定の保存時にアカウントのパスワードを求められます。
    Windowsのパスワードを変更したら、タスクの設定を開き直して入れ直してください
    (忘れると次の実行から失敗します)

ここでつまずく:細かいが実際に起きる罠

「開始(オプション)」を「”」で囲んではいけない

「プログラム/スクリプト」欄は、パスにスペースが含まれるなら「”」で囲むのが正しい書き方です。
ところが「開始(オプション)」欄は逆で、囲むとエラーになります(0x8007010B「ディレクトリ名が無効です」)。
スペースを含むパスでも囲みません。隣り合った欄でルールが逆です。

ネットワークドライブの割り当ては「つないだ人」にしか見えない

Z: のようなドライブ文字は、PC全体の設定ではありません。
ログオンしたときに、そのログオンセッション(ログオン中の作業環境)の中に作られる割り当てです。
だから、次の2通りの消え方をします。

  • 「かかわらず」で動くタスクは、セッションの外で動くため、そこに Z: が存在しない
  • 「最上位の特権」を付けると、通常の権限で割り当てた Z: が管理者権限の側からは見えず、ログオン中でも失敗することがあります

対処はどちらも同じで、ドライブ文字をやめて UNCパス(\\サーバー名\共有名\… の形)で書きます。

途中まで動いている失敗がある:ログで確かめる

batは、途中の行がエラーになっても止まらず次の行へ進むので、
(0x1) でも「前半のコピーは成功、後半だけ失敗」という中途半端な状態がありえます。
作られたはずのファイルが見当たらないときは、C:\Windows\System32 の中も見てください。
現在地がそこのまま管理者権限で動いていた場合、成果物がそこにできていることがあります。

ログを残す(bat1枚かぶせるだけ)

元のbat(例: job.bat)はそのままにして、ログ取り用のbatを同じフォルダにもう1枚作り、
タスクスケジューラにはこちらを登録します。

@echo off
cd /d "%~dp0"
echo ==== %date% %time% ==== >> "%~dp0job_log.txt"
call "%~dp0job.bat" >> "%~dp0job_log.txt" 2>&1
  • 「job.bat」は自分のbatの名前に、「job_log.txt」(2か所)は好きなログの名前に置き換える
  • 2行目の cd は系統1の対策も兼ねる。消すと job.bat 内の相対パスが直らないままになる
  • 「>>」は追記の意味。「>」にすると毎回上書きされて履歴が残らない
  • 「2>&1」はエラーメッセージもログに入れる指定。これが無いと、肝心のエラー文が残らない

タスクスケジューラ自体の「履歴」タブも使えます。
タブ名が「履歴 (無効)」なら、画面右側の「操作」から「すべてのタスク履歴を有効にする」を押します。
ただし履歴に残るのは起動時刻と終了コードだけで、batの中で何が起きたかは上のログにしか残りません。

この記事の確認範囲

画面の名前や項目の並びは、Windows 11 のものです。
Windowsのエディションや設定によって、名前や位置が変わることがあります。

  • 共有フォルダ(\\サーバー名\… や Z: など)は環境ごとの差が大きく、
    UNCパス・pushd/popd・ネットワークドライブの対処だけでは足りないことがあります
  • 早見表に挙げたエラーコードは代表的なものだけで、記事に挙げた原因がすべてではありません
  • 会社のパソコンでは、管理者の設定によってタスクの登録自体が制限されていることがあります

コメント

タイトルとURLをコピーしました