rcmdnk's blog
Last update

20130723_AutoHotKey_200_200

Windowsのキーカスタマイズ等が出来るAutoHotkeyですが、 自作スクリプトの中でファイルを読み込んだりアイコン設定をするためにファイルの位置を指定したりする時に スクリプトのあるディレクトリなどを基準にした相対パスを使ったりします。

その際にスクリプトがリンクだったりした場合 ちょっと混乱したので分かったことのまとめ。

Sponsored Links

A_WorkingDir/A_ScriptDir

スクリプトを起動するとA_WorkingDirA_ScriptDirという変数が自動的に設定されます。

A_WorkingDirは作業ディレクトリで スクリプト内で相対パスを使うとこのディレクトリから始まる相対パスになります。 初期値はそのスクリプトを起動したディレクトリになります。

A_ScriptDirはスクリプトのあるディレクトリになります。

共に最後のパスの区切りのバックスラッシュ(\)(または円マーク)は無い状態になります。 ただし、A_WorkingDirの方はルート(C:\)だけは残ります。 A_ScriptDirの方ではルートでも無し(C:)。

Variables and Expressions

A_WorkingDirに関してはSetWorkingDirと言う組み込みコマンドが用意されていて、

SetWorkingDir, C:\temp

の様にして変更することが可能です。

よくやるのが

SetWorkingDir, %A_ScriptDir%

の様にスクリプトのディレクトリを作業場に設定し直す方法。 通常はA_WorkingDirA_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_WorkingDirA_ScriptDir共に 元のスクリプトがある場所を示します。

なので#Includeしたいファイルやアイコンファイルなど読み込みたいファイルがある場合、 相対パスで指定する場合には元のファイルの位置を基準に置く事になります。

スタートアップフォルダに登録したい場合はメインのファイルだけを おいておけば 後は元のファイルのフォルダで#Includeしたいファイルなどを用意すれば良いことになります。

一方、Windows 10ではシンボリックリンクもOSの機能として元々作れる様になってますが、 この場合ちょっと状況が変わります。

シンボリックリンクなスクリプトを立ち上げると、 A_ScriptDirは元のファイルの位置を示しますが、 A_WorkingDirの方はシンボリックリンクがあるフォルダを示します。

なのでこの場合は A_WorkingDirA_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_ScriptFullPathA_LineFileは同じ値になりますが #includeした先だとA_ScriptFullPathはインクルードする側のファイル、 A_LineFileはされた側のファイルを示します。

A_LineDir的な変数があれば上の様な..を使わなくても済むのですが 現状この様な変数は無いのでファイルのパス名を取ってからディレクトリを..で 辿って取得、という方法が必要になります。

追記ここまで

Sponsored Links
Sponsored Links

« Vim起動時にdeinを使うかどうか対話的に設定する(confirm()) AutoHotkeyでどこでもオートコレクト機能を使う »