ことのはじまり
WSLでは基本的にcronが使えません。もちろん起動すれば使えるのですがなんとなく使わないほうが良さそうな匂いがします。しかし、Windowsにはそもそもタスク スケジューラという高機能な自動実行機能があるのでこれを使うことにします。
タスク スケジューラを起動すると実にさまざまな条件でプログラムを実行できることがわかります。まずはGUIインタフェースを開いてのぞいてみましょう。デフォルトでも様々なタスクが登録されています。スタートアップやサービスを止めていてもいつの間にか動いているプロセスたちは起動時タスクとして登録されていたんですね。
(以降はタスクスケジューラやMicrosoftのドキュメントを参照しながら読み進めてください)
コマンドラインで操作する
タスク スケジューラについてはMicrosoftが詳細なドキュメントを用意してくれています。この中に、Schtasks.exeという項目が見つかりました。コマンドラインで操作できるように用意されているようです。
一通りのオプションが解説されているのですが、筆者が設定したいトリガーは
「任意のユーザーのログオン時 - トリガーされた後、1時間ごとに無期限にくりかえします。」
というGUIで設定できた条件です。
しかし、どうもこの条件はコマンドラインオプションの組み合わせでは実現できそうにありません。こういった複雑な条件には対応できないようです。ただし、オプションの中に /XMLというものがあります。応用編に該当するような設定はXMLで記述して流し込むという方針のようです。
XMLを記述する
、、、のは面倒なのでGUIで設定を作ってそれをひな型にしましょう。
幸い、GUIの「タスク スケジューラ」にはエクスポート機能があります。使いたい条件をGUIでポチポチ選択して、タスク名を右クリックして「エクスポート」を選択します。すると、記述したタスクをXMLとして書き出してくれます。
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2021-05-24T06:37:00.2374197</Date>
<Author>HOSTNAME\shigeokamoto</Author>
<URI>\WSL\IPv6 Enabler</URI>
</RegistrationInfo>
....(以下略)....
これをひな型にすればプログラム操作も面倒ではないでしょう。
内容的には先のRegistrationInfoのURIはタスク名を示しているのですが、schtasks のオプションにてタスク名は指定が必須のようなので外しておいたほうが無難でしょう。
あとカットしないといけない部分は
<Principals>
<Principal id="Author">
<UserId>X-0-0-00-000000000-0000000000-0000000000-0000</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
↓ ↓ ↓ ↓ ↓ ↓ ↓
<Principals>
<Principal>
<LogonType>InteractiveToken</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
UserID等はエクスポートした環境を踏襲したいという場合以外は外したほうがよいでしょう。
必要に応じてActionsの引数にユーザーディレクトリなどが含まれる場合にはアレンジを加えたり、実行時間等の微調整があるのであればプログラムで展開するという感じでしょうか。
注意点としては、このXMLはUTF-16でないといけないようなのでシェルスクリプト等で生成する場合にはコード変換してファイルに出力するようにします。
おまけ:便利機能?
Windows操作において管理者権限が必要とされる場合にはUACで確認が求められます。しかし、よく使うものでそこは確認不要というような操作があった場合、タスクに登録しておけばスケジュールには依存せず schtasks コマンドを使って実行できるようです。<RunLevel>HighestAvailable</RunLevel>
が設定されているタスクは実行ユーザーが持つ最上位の権限で実行するオプションですが、スケジュール実行なのでUACの確認はありません。schtasksで実行する際にも確認なしに権限昇格が可能です。
具体的には以下のように実行します。
shtasks.exe /RUN /I /TN 'タスク名'