URLショートカットからURLを読み出す
お気に入りなどに登録されているインターネットショートカットからURLを取り出したいことがある。そのような場合はCOMインターフェースのIUniformResourceLocatorを通じてアクセスする。ショートカットファイルの拡張子には「.url」を指定する。
IUniformResourceLocator::GetURLはURLが取得できていないにも関わらず成功を示すS_FALSEを返すことがあるので実装に注意する。
依存環境:ATL#include "atlstr.h"
#include <shlobj.h>
#include <intshcut.h>
//
// URLショートカットからのURL読み込み
//
// pszFileに指定されたURLショートカットを読み込みます。拡張子に「.url」を指定してください。
//
bool GetInternetShortcut(LPCTSTR pszFile,CAtlString* pstrURL)
{
HRESULT hr;
LPTSTR pszURL;
IMalloc* pIMalloc;
IPersistFile* pIPersistFile;
IUniformResourceLocator* pIUniformResourceLocator;
if(pstrURL == NULL)
return false;
*pstrURL = _T("");
pIUniformResourceLocator = NULL;
hr = ::CoCreateInstance(CLSID_InternetShortcut,NULL,CLSCTX_INPROC_SERVER,IID_IUniformResourceLocator,(void**)&pIUniformResourceLocator);
if(pIUniformResourceLocator == NULL || FAILED(hr))
return false;
hr = pIUniformResourceLocator->QueryInterface(IID_IPersistFile,(void**)&pIPersistFile);
if(pIPersistFile)
{
#ifdef _UNICODE
hr = pIPersistFile->Load(pszFile,STGM_READ | STGM_SHARE_DENY_NONE);
#else
WCHAR* pwszUnicode;
int nLen;
//Unicode変換
nLen = ::MultiByteToWideChar(CP_ACP,0,pszFile,-1,NULL,0);
pwszUnicode = new WCHAR[nLen + 1];
if(pwszUnicode == NULL)
{
pIPersistFile->Release();
pIUniformResourceLocator->Release();
return false;
}
nLen = ::MultiByteToWideChar(CP_ACP,0,pszFile,-1,pwszUnicode,nLen + 1);
if(nLen == 0)
hr = E_FAIL;
hr = pIPersistFile->Load(pwszUnicode,STGM_READ | STGM_SHARE_DENY_NONE);
delete pwszUnicode;
#endif
}
if(pIUniformResourceLocator)
hr = pIUniformResourceLocator->GetURL(&pszURL);
if(hr == S_FALSE) //S_FALSEが返ることがある!これはSUCCEEDED(hr)なので注意!
hr = E_FAIL;
if(SUCCEEDED(hr))
*pstrURL = pszURL;
pIMalloc = NULL;
if(SUCCEEDED(hr))
hr = ::SHGetMalloc(&pIMalloc);
if(pIMalloc && SUCCEEDED(hr))
pIMalloc->Free(pszURL);
if(pIMalloc)
pIMalloc->Release();
if(pIPersistFile)
pIPersistFile->Release();
if(pIUniformResourceLocator)
pIUniformResourceLocator->Release();
return SUCCEEDED(hr) ? true : false;
}
void Test(void)
{
bool ret;
CAtlString strURL;
//COM初期化
::CoInitialize(NULL);
ret = GetInternetShortcut(_T("c:\\test.url"),&strURL);
if(ret)
::MessageBox(NULL,strURL,_T(""),MB_OK);
else
::MessageBox(NULL,_T("URLの読み込みに失敗しました"),_T(""),MB_OK);
//COM開放
::CoUninitialize();
}
