「あのファイル、Dropboxに入れといて」
「分かりましたー」
–30分後–
「…まだ?」
「今さっき入れました!」
いや絶対俺の「まだ?」が先。
こういうことって結構ありますよね。
Dropboxの共有フォルダは通知をONにすることもできますが、常に誰かがファイルを更新しているような環境だと通知が来すぎてウザい。ただ通知をOFFにすると、今度は急ぎのファイルが共有されたかどうか、フォルダを開かないと分からない。
ならそのチェック、AutoHotKeyに任せましょう。
フォルダ監視スクリプト
まずは例によって出来上がり。
;フォルダ監視スクリプト
MsgBox, ,,フォルダ監視 スタート,0.3
#Persistent
SetTimer, Monitor, 1000
return
Monitor:
Loop, D:\Dropbox\共有フォルダ\*
{
now := A_Now
EnvSub, now, A_LoopFileTimeAccessed, Seconds
If (now < 10){
SetTimer, Monitor, off
MsgBox ファイル更新: `n%A_LoopFileName%
Sleep, 10000
SetTimer, Monitor, on
}
}
このコードをメインスクリプトの最初のInclude文より前に置きます。別ファイルにする場合は<b>最初にインクルード</b>してください。
リロードするとダイアログが出てくるはずです。(0.3秒で自動的に消えます)
指定したフォルダにファイルを追加してみます。今回はDropbox内の「共有フォルダ」に何らかのファイルが追加、もしくは更新された場合、その更新が通知されます。
このコードは大きく2つに分けることができます。1つは5行目までの「タイマーを走らせるコード」、もう1つは「タイマーそのもの」です。
以下でこのコードの詳細を解説していこうと思います。まずはタイマーを走らせる部分から見ていきましょう。
#Persistent
スクリプトを常駐状態にします。常駐状態になったスクリプトはAuto-executeセクションが終了した後も終了せず、残り続けます。
Auto-executeセクションとは?
メインで走るスクリプトファイルや、インクルードされるファイルの中で、
- 最初のReturn
- 最初のExit
- 最初のホットキーラベル
- ファイルの終わり
上記のいずれかに達した場合、そこまでをAuto-execute(起動時に自動的に実行される)セクションと呼びます。
このコードにはホットキーがありません。Auto-executeセクションに配置することによって、ホットキーを押さなくてもコードは実行され、そのまま常駐状態に入ります。
SetTimer
SetTimer, Label [, Period|On|Off, Priority]
;Labelに対応したタイマーをON/OFFする
引数
SetTimerの引数は最低1つ、最大3つ。
仮引数名 | 値 | 例 |
---|---|---|
Label (必須) | タイマーの名前をラベルとして設定 | Monitor |
Period or On/Off | タイマー実行の間隔(ミリ秒) or タイマーのON/OFF | 1000 |
Priority | 割り込み優先度。設定値より低いスレッドは割り込み不可 | 1 | -1(デフォルトは0) |
Priorityに関してはスレッドの話になってくるので、今回は割愛。
上に示したコードではSetTimer, Monitor, 1000
で「Monitorというラベルが付いたタイマーを、1秒間隔で実行する」という意味になります。
すぐ下の行にはMonitor:
と記述されています。これがタイマーのラベルです。ラベル名は自由に付けることができますが、最後のコロンを忘れずに。変更した場合はSetTimerの引数も書き換えましょう。
さらに下の行ではSetTimer, Monitor, off
で一旦タイマーをOFFにし、ダイアログを表示した後でSetTimer, Monitor, on
で再びタイマーをスタートさせています。
Loop
ここからコードの後半。タイマーの設定部分です。
Monitor:
Loop, D:\Dropbox\共有フォルダ\*
{
now := A_Now
EnvSub, now, A_LoopFileTimeAccessed, Seconds
...
ラベル以下の行はタイマーの内側。2行目に使用されているコマンドはLoopですが、Loopには引数によって2種類の働きがあります。
今回使用しているのはフォルダを引数に取る使い方。この記述だとファイルの追加や更新にのみ対応しています。
オプションによってフォルダの更新を検知したり、サブフォルダを対象にしたり色々と変更できます。Loopコマンドのページで詳しく記載しているので、試してみてください。
EnvSub
変数宣言を挟んでEnvSub
です。
EnvSub, Var, Value[, TimeUnits]
第三引数を省略すると、EnvSubは「VarからValueを引き、Varにその答えを代入する」という非常にシンプルなコマンドです。
x := 10
EnvSub, x, 2
MsgBox, %x% ;8が出力される
EnvSubの第三引数
今回の場合は第三引数に「Seconds」が入っています。これによってこの一文は日付時刻同士の計算であると明言し、その結果をどのような単位で表すかを指定しています。
EnvSub, now, A_LoopFileTimeAccessed, seconds
;変数nowと%A_LoopFileTimeAccessed%との差を、秒単位でnowに代入する
第三引数の種類
値 | 意味 |
---|---|
Days | 両者の差を日単位で表す |
Hours | 両者の差を時間単位で表す |
Minutes | 両者の差を分単位で表す |
Seconds | 両者の差を秒単位で表す |
YYYYMMDDHH24MISS形式
変数nowに代入されているA_Now
とA_LoopFileTimeAccessed
は、それぞれ「現在日時」と「ファイルの最終アクセス日時」をYYYY(年)MM(月)DD(日)HH24(時間)MI(分)SS(秒)形式で表した整数です。
今回はこの2つの差を取り、秒単位で現在日時から何秒前にアクセスされたファイルなのかを判定しています。
残りのコード
後に続くコードでは特別なことはしていませんが、一応おさらいとして。
If (now < 10){
SetTimer, Monitor, off
MsgBox ファイル更新: `n%A_LoopFileName%
Sleep, 10000
SetTimer, Monitor, on
}
}
EnvSub
の結果が10未満(現在日時とファイルの最終アクセス日時が10秒未満)の時、ダイアログを表示しています。