ショートカットの情報の取得

ショートカットからリンク先を取得する

前回はショートカットを作成する方法を説明したので、今回はショートカットファイル(.lnk)からリンク先ファイル名を取得する方法を説明します。

シェルリンクオブジェクトを作成し、 IShellLink インターフェースと IPersistFile インターフェースの機能を使用するということは前回と同じです。ただし、今回は IPersistFile インターフェースのファイルロードの機能と、IShellLink インターフェースのオブジェクト情報取得の機能を使うことになります。

手順は以下のようになります。(COM ライブラリの初期化・クローズは自動的に行なわれるため、今後は記述しません。)

  1. シェルリンクオブジェクトを作成し、 IShellLinkIPersistFile のインターフェースポインタを取得する。

  2. IPersistFile::Load メソッドにより、シェルリンクファイルからオブジェクトの内容を初期化する。

  3. IShellLink::GetPath メソッドにより、実行ファイル名を取得する。

  4. IShellLinkIPersistFile インターフェースを解放する。

シェルリンクオブジェクト作成とインターフェース取得

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

ここでは、リンク先ファイル名の指定しかしていませんが、以下のメソッドを使って、いろいろな属性を取得することができます。

IShellLink::GetIconLocation
アイコンを取得
IShellLink::GetArguments
コマンドラインを取得
IShellLink::GetHotkey
ホットキーを取得
IShellLink::GetShowCmd
ウィンドウの初期表示状態を取得

インターフェース解放

前回と同じく、使用したインターフェースの 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