詳細が公開されていないソフト内のインターフェースをホストしたい場合など、DLL内にあるCLSIDを取得したいことがごくまれにある。
LoadTypeLib でDLLを読み込みITypeLibを取得してから、ITypeIfo::GetTypeAttr()を使うことで取得できる。
Shell.Explorer.1 Shell.Explorer.2 InternetExplorer.Application.1 Shell.UIHelper.1 ShellNameSpace.ShellNameSpace.1 ShellShellNameSpace.ShellShellNameSpace.1
bool Test()
{
bool ret;
size_t i;
size_t nSize;
HRESULT hr;
WCHAR* pwszProgID;
CAtlArray<GUID> aguidCoClass;
//shdocvw.dll内のCLSIDを取得
ret = CLSIDFromDLLFile(_T("c:\\windows\\system32\\shdocvw.dll"),aguidCoClass);
if(ret == false)
return false;
nSize = aguidCoClass.GetCount();
for(i = 0; i < nSize; i++)
{
//GUIDからプログラムIDの文字列に変換してATLTRACEで出力
pwszProgID = NULL;
hr = ::ProgIDFromCLSID(aguidCoClass[i],&pwszProgID);
if(SUCCEEDED(hr))
{
ATLTRACE("%s\n",(CAtlString)pwszProgID);
::CoTaskMemFree(pwszProgID);
}
}
return true;
}
#include "atlstr.h"
#include "atlcoll.h"
/*!
* \brief
* DLL中のCLSIDを取得する
*
* \param[in] pszFile
* タイプライブラリをチェックするDLLファイルのパス
*
* \param[out] aguidCoClass
* COCLASSとして登録されているGUIDの配列
*
* \retval true 成功(1つ以上取得できた)
* \retval false 失敗(1つも取得できなかった)
*
*/
bool CLSIDFromDLLFile(LPCTSTR pszFile,CAtlArray<GUID>& aguidCoClass)
{
UINT i;
UINT nCount;
HRESULT hr;
TYPEATTR* pTypeAttr;
CComPtr<ITypeLib> pITypeLib;
CComPtr<ITypeInfo> pITypeInfo;
aguidCoClass.RemoveAll();
hr = ::LoadTypeLib((CAtlStringW)pszFile,&pITypeLib);
if(FAILED(hr))
return false;
nCount = pITypeLib->GetTypeInfoCount();
for(i = 0; i < nCount ; i++)
{
pITypeInfo = NULL;
hr = pITypeLib->GetTypeInfo(i,&pITypeInfo);
if(FAILED(hr))
continue;
pTypeAttr = NULL;
hr = pITypeInfo->GetTypeAttr(&pTypeAttr);
if(FAILED(hr))
continue;
if(pTypeAttr->typekind == TKIND_COCLASS)
{
aguidCoClass.Add(pTypeAttr->guid);
}
pITypeInfo->ReleaseTypeAttr(pTypeAttr);
}
return aguidCoClass.GetCount() ? true : false;
}
