前回はショートカットを作成する方法を説明したので、今回はショートカットファイル(.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