山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他COMを使用してショートカットのリンク先を取得する(32/64bit)
概要
COMのIShellLink,IPersistFileインターフェースを使用してショートカットのリンク先を取得します。
          下図の実行例は、Dドライブに本プログラムと本プログラムへのショートカットをtestという名前で保存し、本プログラム(リンク先とタイトルのついたダイアログボックス)を実行した結果です。
          比較のためDドライブの内容をエクスプローラで表示し、ショートカットtestのプロパティを表示しています。
          
テスト環境
コンパイラ
Visual C++ 2008/2013 Express 32/64bit UNICODE実行環境
Windows XP Professional Service Pack 3 32bit(Virtual Box上の仮想マシーン)Windows 7 Enterprise Service Pack 1 64bit
プログラムソースの概要
getshortcut.cpp
WinMain
COMの初期化
CoInitialize APIによりCOMを初期化します。ショートカットを扱うための準備
CoCreateInstance関数によりIShellLinkオブジェクトを作成します。QueryInterface関数によりIPersistFileインターフェースの作成します。
複数のショートカットを扱う場合でも同時に1個しか扱わない場合は準備は1回で結構です。(STAでCOMを初期化しているのでスレッド単位で必要)
ショートカットの読み込み
Load
IPersistFileのメンバであるLoadにショートカットのファイル名を指定して呼び出すとショートカットが呼び出されます。Resolve
IShellLinkのメンバであるResolveを呼び出すとショートカットのリンク先が存在しない場合、以下のようなメッセージが表示されます。大量のショートカットを扱う場合、このようなメッセージは煩わしいので、Resolveを読み出さないようにします。この場合、リンク先が存在しなくてもショットカットのリンク先が表示されます。ダウンロードのgetshort2.zipはResolveを省いていますので、動作を比較すると理解できると思います。

GetPath
IShellLinkのメンバであるGetPathを呼び出すとリンク先が取得できます。複数のショートカットを扱う場合は、Loadから繰り返します。
ショートカット使用後の後始末
IShellLink,IPersistFileをReleaseで解放します。COMの解放
CoUninitialize APIによりCOMを解放します。ソースコード
getshortcut.cpp
//      指定されたショートカットファイル(test.lnk)のリンク先を取得して表示
//      リンク先が存在しない場合は、エラーメッセージが表示されます
//      Visual C++ 2008/2013 Express (UNICODE 32/64bit)
#include <windows.h>
#include <shobjidl.h>
#include <shlguid.h>
#include <tchar.h>
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,LPSTR lpsCmdLine, int nCmdShow){
        //      ショートカットのファイル名
        TCHAR* file_pass=_TEXT("test.lnk");
        
        if( FAILED( CoInitialize(NULL) )){      //      COMの初期化 STA(シングルスレッドアパートメント)
                MessageBox(0,_TEXT("COMの初期化に失敗しました"),_TEXT("エラー"),MB_OK);
                return -1;
        }
        TCHAR pass[MAX_PATH];   //      ショートカットのリンク先
        IShellLink              *m_pShellLink=NULL;     
        IPersistFile    *m_pPersistFile=NULL;
//      IShellLinkオブジェクトを作成
        if(CoCreateInstance( CLSID_ShellLink , NULL , CLSCTX_INPROC_SERVER ,IID_IShellLink ,(LPVOID *)&m_pShellLink)==S_OK){
//      IPersistFileインターフェースの作成
                if(m_pShellLink->QueryInterface( IID_IPersistFile, (LPVOID *)&m_pPersistFile )==S_OK){
//      ショートカットファイルの読み込み 複数のショートカットを処理する場合は以下6行を繰り返す
                        if(m_pPersistFile->Load( file_pass, STGM_READ )==S_OK){
                                if( m_pShellLink->Resolve( NULL, 0 )==NOERROR){      //      リンク先にファイルがない場合はエラーメッセージを表示する
                                        m_pShellLink->GetPath(pass,sizeof(pass)/sizeof(TCHAR),NULL,SLGP_UNCPRIORITY);        //      リンク先取得
                                        MessageBox(0,pass,_TEXT("リンク先"),MB_OK);
                                }
                        }else{
                                MessageBox(0,file_pass,_TEXT("ショートカットファイルが見つかりません。"),MB_OK);
                        }
                        m_pShellLink->Release();     //      IShellLinkオブジェクトの解放
                        m_pPersistFile->Release();   //      IPersistFileインターフェースの解放
                }
        }
        CoUninitialize();       //      COMの解放
        return (int)0;
}
実行ファイルとソースファイルのダウンロード(getshortcut.zip) Resolve使用
          実行ファイルとソースファイルのダウンロード(getshortcut2.zip) Resolve未使用
          
      Copyright (C) 2012 山本ワールド All Rights Reserved.
    
    
  