前回はショートカットを作成する方法を説明したので、今回はショートカットファイル(.lnk)からリンク先ファイル名を取得する方法を説明します。
シェルリンクオブジェクトを作成し、 IShellLink インターフェースと IPersistFile インターフェースの機能を使用するということは前回と同じです。ただし、今回は IPersistFile インターフェースのファイルロードの機能と、IShellLink インターフェースのオブジェクト情報取得の機能を使うことになります。
手順は以下のようになります。(COM ライブラリの初期化・クローズは自動的に行なわれるため、今後は記述しません。)
シェルリンクオブジェクトを作成し、 IShellLink と IPersistFile のインターフェースポインタを取得する。
IPersistFile::Load メソッドにより、シェルリンクファイルからオブジェクトの内容を初期化する。
IShellLink::GetPath メソッドにより、実行ファイル名を取得する。
IShellLink、IPersistFile インターフェースを解放する。
createobj 命令でシェルリンクオブジェクトを作成して IShellLink インターフェースを取得し、その後 queryinterface 命令で IPersistFile インターフェースを取得するというのは前回と同じなので、詳しい説明は省略します。
前回はオブジェクト作成時にまず IShellLink インターフェースを取得し、そこから IPersistFile インターフェースを取得するという手順でしたが、先に IPersistFile インターフェースを取得して、後で IShellLink インターフェースを取得しても問題無いです。
作成されたシェルリンクオブジェクトは、データが何も設定されていない未初期化の状態です。前回は IShellLink インターフェースのメソッドによりデータを設定していきましたが、今回はファイルの内容を元にしてオブジェクトの初期化をします。
シェルリンクファイル(ショートカットファイル)の内容をもとにオブジェクトを初期化するには IPersistFile::Load メソッドを呼び出します。
HRESULT Load( LPCOLESTR pszFileName, //ファイル名 DWORD dwMode //アクセスモード );
このメソッドのインデックスは 5 です。 pszFileName はファイル名文字列のアドレスを指定します。前回と同じく、Unicode文字列で指定しなくてはなりません。 dwMode パラメータは、ここでは 0 (STGM_READ) を指定します。
#include "unicode.as" ; ショートカットファイル名 sdim lnkfile, 260 lnkfile = curdir + "\\HSP_ShortCut.lnk" ; Unicode に変換する sdim w_lnkfile, 520 ; Unicode を格納する変数 to_uni w_lnkfile, lnkfile, -1 ; IPersistFile::Load メソッド呼び出し getptr pm, w_lnkfile ; ファイル名(Unicode) pm.1 = 0 ; STGM_READ icall pPersistFile, 5, pm, 2
次は、オブジェクトが持つデータから、リンク先のファイル名の情報を取得します。これには IShellLink::GetPath メソッドを呼び出します。
HRESULT STDMETHODCALLTYPE GetPath( LPTSTR pszFile, //ファイル名を格納するバッファ int cchMaxPath, //バッファサイズ WIN32_FIND_DATA *pfd, //WIN32_FIND_DATA構造体 DWORD fFlags //パスのタイプ );
このメソッドのインデックスは 3 です。 pszFile にはファイル名を格納する文字列型変数のアドレスを、 cchMaxPath にはそのサイズを指定します。 pfd には、ファイル情報を格納する WIN32_FIND_DATA 構造体のアドレスを指定します。fFlags は、通常は 0 を指定します。
sdim targetfile, 260 ; リンク先ファイル名を格納する変数 dim finddata, 80 ; WIN32_FIND_DATA 構造体 ; IShellLink::GetPath メソッド呼び出し getptr pm, targetfile ; ファイル名を格納するバッファのアドレス pm.1 = 260 ; バッファサイズ getptr pm.2, finddata ; WIN32_FIND_DATA 構造体のアドレス pm.3 = 0 icall pShellLink, 3, pm, 4
ここでは、リンク先ファイル名の指定しかしていませんが、以下のメソッドを使って、いろいろな属性を取得することができます。
前回と同じく、使用したインターフェースの Release メソッドを呼び出す(release 命令を実行する)ことによって参照カウントを減らし、オブジェクトを解放します。
release pPersistFile release pShellLink
#include "llmod.as" #include "unicode.as" #include "rrmod/com/lollipop.as" ; クラスIDの定義 #define CLSID_ShellLink "{00021401-0000-0000-C000-000000000046}" ; インターフェースIDの定義 #define IID_IShellLinkA "{000214EE-0000-0000-C000-000000000046}" #define IID_IPersistFile "{0000010b-0000-0000-C000-000000000046}" sdim targetfile, 260 sdim lnkfile, 260 ; ショートカットファイル名 lnkfile = curdir + "\\HSP_ShortCut.lnk" ; オブジェクトの作成・IShellLink インターフェース取得 createobj pShellLink, CLSID_ShellLink, IID_IShellLinkA if pShellLink == 0 { dialog "IShellLink インターフェースを取得できません。", 1 goto *lb_quit } ; IPersistFile インターフェース取得 queryinterface pPersistFile, pShellLink, IID_IPersistFile if pPersistFile == 0 { dialog "IPersistFile インターフェースを取得できません。", 1 goto *lb_quit } ; ショートカットファイル名を Unicode に変換する sdim w_lnkfile, 520 ; Unicode を格納する変数 to_uni w_lnkfile, lnkfile, -1 ; IPersistFile::Load メソッド呼び出し getptr pm, w_lnkfile ; ファイル名(Unicode) pm.1 = 0 ; STGM_READ icall pPersistFile, 5, pm, 2 if dllret < 0 { dialog "ショートカットファイルをロードできません。", 1 goto *lb_quit } ; IShellLink::GetPath メソッド呼び出し dim finddata, 80 ; WIN32_FIND_DATA 構造体 getptr pm, targetfile ; ファイル名を格納するバッファのアドレス pm.1 = 260 ; バッファサイズ getptr pm.2, finddata ; WIN32_FIND_DATA 構造体のアドレス pm.3 = 0 icall pShellLink, 3, pm, 4 if dllret < 0 { dialog "ファイル名を取得できません。", 1 goto *lb_quit } dialog "リンク先ファイル名は\n" + targetfile + "\nです。" *lb_quit ; 終了処理(インターフェース解放) if pPersistFile { release pPersistFile pPersistFile = 0 } if pShellLink { release pShellLink pShellLink = 0 } end