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

Visual C++プログラミングのメモ

【Visual C++ 2008】【Win32】

 ショートカット(*.lnk)のフルパスから、リンク先のフルパスを取得する方法。


#include <shobjidl.h>
#include <shlguid.h>

// hwnd     呼び出し元のウィンドウハンドル
// shortcut ショートカットのフルパスのポインタ
// fullPath リンク先のフルパスのポインタ
BOOL CXxxxx::getFullPathFromShortcut(HWND hwnd, const wchar_t *shortcut, wchar_t *fullPath)
{
    HRESULT hres;
    IShellLink *psl = NULL;

    // 取得するリンク先のフルパスの初期化
    *fullPath = 0;

    // COM初期化
    CoInitialize(NULL);

    // IShellLinkインタフェース取得
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
        IID_IShellLink, (void**)&psl);

    if (SUCCEEDED(hres))
    {
        IPersistFile *ppf = NULL;

        // IPersistFileインタフェース取得
        hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);

        if (SUCCEEDED(hres))
        {
            // ショートカットの読み込み
            hres = ppf->Load(shortcut, STGM_READ);

            if (SUCCEEDED(hres))
            {
                // リンク先の解決
                // リンク先のファイルが存在しない場合、エラーメッセージボックスを
                // 表示する。そのために、親ウィンドウのハンドルを指定する。
                // この行をコメントアウトした場合、実際に存在するかどうかに
                // 関係無く、リンク先を返す。
                hres = psl->Resolve(hwnd, 0);

                if (SUCCEEDED(hres))
                {
                    // リンク先のフルパス取得
                    hres = psl->GetPath(fullPath, _MAX_PATH, NULL, 0);

                    if (SUCCEEDED(hres))
                    {
                        // IPersistFileインタフェース解放
                        ppf->Release();

                        // IShellLinkインタフェース解放
                        psl->Release();

                        // COM閉じる
                        CoUninitialize();

                        return TRUE;
                    }
                }
            }
        }

        // IPersistFileインタフェース解放
        if (ppf != NULL)
        {
            ppf->Release();
        }
    }

    // IShellLinkインタフェース解放
    if (psl != NULL)
    {
        psl->Release();
    }

    // COM閉じる
    CoUninitialize();

    return FALSE;
}

(メモ)

  • 「MFCアプリケーションウィザード」にてアプリケーションを生成した場合、 上記の関数のコンパイルに必要なincludeはstdafx.hのみでよい。 (上記の関数自体はMFCを使用していない)
  • 以下のソースを大幅に参考にした
    • MSDNライブラリの「Shell Links」の「Resolving a Shortcut」のExample (ResolveIt関数)
    • C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\filecore.cpp のAfxResolveShortcut関数
  • MSDNライブラリの「IShellLink」「CoInitialize」「CoUninitialize」「CoCreateInstance」 「IPersistFile」「SUCCEEDED」を参照のこと