Windowsのキーカスタマイズ等が出来るAutoHotkeyですが、 自作スクリプトの中でファイルを読み込んだりアイコン設定をするためにファイルの位置を指定したりする時に スクリプトのあるディレクトリなどを基準にした相対パスを使ったりします。
その際にスクリプトがリンクだったりした場合 ちょっと混乱したので分かったことのまとめ。
A_WorkingDir/A_ScriptDir
スクリプトを起動するとA_WorkingDir
とA_ScriptDir
という変数が自動的に設定されます。
A_WorkingDir
は作業ディレクトリで
スクリプト内で相対パスを使うとこのディレクトリから始まる相対パスになります。
初期値はそのスクリプトを起動したディレクトリになります。
A_ScriptDir
はスクリプトのあるディレクトリになります。
共に最後のパスの区切りのバックスラッシュ(\
)(または円マーク)は無い状態になります。
ただし、A_WorkingDir
の方はルート(C:\
)だけは残ります。
A_ScriptDir
の方ではルートでも無し(C:
)。
A_WorkingDir
に関してはSetWorkingDir
と言う組み込みコマンドが用意されていて、
SetWorkingDir, C:\temp
の様にして変更することが可能です。
よくやるのが
SetWorkingDir, %A_ScriptDir%
の様にスクリプトのディレクトリを作業場に設定し直す方法。
通常はA_WorkingDir
とA_ScriptDir
は同じですが、
下に書くリンクを利用したりする時にきちんと確認することが必要になります。
ファイルをIncludeした場合、そのファイル内でのA_ScriptDir
外部ファイルを読み込んだ場合、
その外部ファイル内でA_ScriptDir
を見ると
呼んだファイルの側のディレクトリになっています。
- C:\Users\User\Documents\Main.ahk
- C:\Users\User\Documents\include\Sub.ahk
みたいなファイルがあって、Main.ahkの中で
#Include include\Sub.ahk
みたいに呼んでSub.ahkの中で
Msgbox,
(
A_ScriptDir: %A_ScriptDir%
)
とかしてみるとA_ScriptDir: C:\Users\User\Documentsと出ます。
A_ScriptNameというスクリプトの名前が入る変数もありますが、
これも#Include
先で見てもMain.ahkとなり、
基本これらの変数は常に最初に立ち上げるファイルの物になります。
なのでちょっと注意が必要なのはスクリプト中で#Include
などを使ってる
ファイルをさらに他から読み込む場合などです。
その読み込まれる側のスクリプトの中で
SetWorkingDir %A_ScriptDir%
とか%A_ScriptDir%\SubSub.ahk
みたいに相対パスで指定すると直接このスクリプトを呼んだ場合と
#Include
した場合とでパスが変わってきてしまいます。
この辺上手くやる方法があまり見つからないので、
結論としてはファイルを#Include
したい場合は
全てのファイルを同じフォルダーの中に入れて親ファイルのA_ScriptDir
の
下に必ずあるような状態で読み込む形にするのが安全です。
追記: 2017/08/24
このような場合に備えてA_LineFile
を使うと問題を解決できます。
(下記A_LineFile
の章参照。)
追記ここまで
リンクファイルを起動した場合
AutoHotkeyのスクリプトのリンクを作ってそれを立ち上げた場合にちょっと注意が必要になります。 スタートアップ等に登録して起動時に立ち上げるときなどは ショートカットをスタートアップフォルダに置くと思うのでそういった時。
ショートカットのスクリプトを起動した場合、
A_WorkingDir
、A_ScriptDir
共に
元のスクリプトがある場所を示します。
なので#Include
したいファイルやアイコンファイルなど読み込みたいファイルがある場合、
相対パスで指定する場合には元のファイルの位置を基準に置く事になります。
スタートアップフォルダに登録したい場合はメインのファイルだけを
おいておけば
後は元のファイルのフォルダで#Include
したいファイルなどを用意すれば良いことになります。
一方、Windows 10ではシンボリックリンクもOSの機能として元々作れる様になってますが、 この場合ちょっと状況が変わります。
シンボリックリンクなスクリプトを立ち上げると、
A_ScriptDir
は元のファイルの位置を示しますが、
A_WorkingDir
の方はシンボリックリンクがあるフォルダを示します。
なのでこの場合は
A_WorkingDir
とA_ScriptDir
が違うフォルダを指すことになります。
こういった場合があると色々面倒なので、
SetWorkingDir %A_ScriptDir%
なり呼ぶ時に必ず%A_ScriptDir%
を付けた絶対パスにしておいた方が良いです。
アプリ化した場合
Ahk2Exe でAutoHotKeyのスクリプトをアプリ化することが出来ますが この場合にもメニューアイコンやトレイアイコンに外部のアイコンファイルなどを使っている場合には それらはアプリ内に取り込まれない様です。
従ってアプリ化した場合にもこれらのファイルをアプリと同じフォルダに入れるなりして アクセス出来る様にする必要があります。
A_LineFile
追記: 2017/08/24
見落としていましたがAutoHotkeyにはA_LineFile
という組み込み変数があります。
この変数にはそれが実行される行があるファイルのパスが入っています。
つまり#include
した場合でもその取り入れた先のファイルのパスが分かります。
これを使うと、
- C:\Users\User\Documents\Main.ahk
- C:\Users\User\Documents\include\Sub.ahk
- C:\Users\User\Documents\include\subsub\Subsub.ahk
みたいなファイルがあって、Main.ahkの中で
#Include include\Sub.ahk
とした場合でもSub.ahkの中で
#Include %A_LineFile%\..\subsub\Subsub.ahk
としてあげればこの部分が
#include C:\Users\User\Documents\include\Sub.ahk\..\subsub\Subsub.ahk**
と展開されてSubsub.ahk
を常に捉える事が出来る様になります。
Unixな操作に慣れているとちょっと気持ち悪いのがファイルの後に..
を使って一つ上(つまりはそのファイルがあるディレクトリ)
に戻っているところですが、
Windowsではこういうことが出来る様です。
コマンドプロンプトやPowerShellでdir
とかls
で試してみると分かります。
ちなみにスクリプトのファイルのパスを表すA_ScriptFullPath
という変数がありますが、
通常はこのA_ScriptFullPath
とA_LineFile
は同じ値になりますが
#include
した先だとA_ScriptFullPath
はインクルードする側のファイル、
A_LineFile
はされた側のファイルを示します。
A_LineDir
的な変数があれば上の様な..
を使わなくても済むのですが
現状この様な変数は無いのでファイルのパス名を取ってからディレクトリを..
で
辿って取得、という方法が必要になります。
追記ここまで