タスクスケジューラ起動のプログラムでコンソールを表示しない
目次
はじめに
タスクスケジューラで .bat
ファイルやコンソールアプリを実行すると、黒いウィンドウ(コンソール)が一瞬表示されます。
この黒いウィンドウの正体はコンソールホストウィンドウと呼ばれるものです。
Windows がコンソールアプリ(.bat ファイルは cmd.exe というコンソールアプリで実行されます)を起動する時、コンソールホスト(conhost.exe)が起動され、そのコンソールホストにより黒い画面(コンソールホストウィンドウ)が表示されます。コンソールアプリケーションはコンソールホストウィンドウを経由して入出力を行うことになります。
コンソールアプリとコンソールホストの関係
flowchart TD A("コンソールアプリ<br> (プロセスID: XXXX)") <-->|"標準入出力 (stdin/stdout/stderr)"| B("コンソールホスト(conhost.exe プロセスID: YYYY)") B <--> |"コンソール<br>ホストウィンドウ<br>(黒いウィンドウ)"| C[ユーザーの画面<br>キーボード入力]
PowerShell を使用して、コンソールを非表示にしてみる(失敗)
PowerShell で引数 -WindowStyle Hidden
を指定すると、コンソールホストにウィンドウを非表示にするように指示を出せます。
powershell -WindowStyle Hidden -Command "Start-Process [プログラム] -WindowStyle Hidden"
1つ目の -WindowStyle Hidden
は PowerShell
自体のウィンドウを非表示にして起動します。
2つ目の -WindowStyle Hidden
は指定したプログラムを非表示で実行します。
例)C:\var\ほげ.bat
を実行
powershell -WindowStyle Hidden -Command "Start-Process 'C:\var\ほげ.bat' -WindowStyle Hidden"
このコマンドを起動済みのコマンドプロンプトから実行すると、コマンドプロンプトが最小化され、実行が開始されます。タスクバーのコマンドプロンプトをクリックするとウィンドウ表示に戻り、他のウィンドウは表示されません。
一見、期待通りに動作しているように思えますが「ファイル名を指定して実行(Win + R)」で、このコマンドを実行すると、黒いウィンドウが一瞬表示されてしまいます。これはアプリケーションの起動時にコンソールホストウィンドウが先に表示されてしまい、その後で -WindowStyle Hidden
が適用されるのが原因です。タスクスケジューラに登録した場合も同様に黒いウィンドウが一瞬表示されることになります。
解決策
1VB Script(WSH) を使用する
wscript.exe はコンソールアプリケーションではなく GUI アプリケーションです。そのため、実行時にコンソールホストウィンドウは表示されません。(cscript.exe はコンソールアプリなので、コンソールホストウィンドウが表示されます)
wscript.exe /e:vbscript /b "CreateObject(""WScript.Shell"").Run ""C:\var\ほげ.bat"", 0, False"
- /e:vbscript
引数で渡したコードを VB Script として実行します - /b
警告、スクリプト エラー、または入力プロンプトを表示しないバッチモードを指定します - CreateObject("WScript.Shell").Run
- 第1引数: 実行するプログラム
- 第2引数: ウィンドウスタイル(0: 非表示)
- 第3引数: False: 非同期実行
タスクスケジューラに登録する場合
- プログラム/スクリプト
wscript.exe
- 引数の追加(オプション)
/e:vbscript /b "CreateObject(""WScript.Shell"").Run ""C:\var\ほげ.bat"", 0, False"
2「ログオン状態にかかわらず実行」を選択する
タスクスケジューラーのタスクのプロパティ > 全般タブの ユーザーがログオンしているかどうかにかかわらず実行する
を選択します。これを選択することでタスクは非対話型モードで実行されます。非対話型モードの場合、コンソールホストウィンドウは表示されません。
図1 タスクスケジューラ
- 非対話型モードの注意点
- ユーザーのデスクトップとは切り離されています
- Excel などの GUI アプリが実行できない場合があります
- ドライブレターを指定したネットワークドライブは見えません(UNCパスなら見えるはずです)
- 実行するユーザーに「バッチジョブとしてログオンする権利」が必要です