DLLファイル名からCLSIDを取得する

詳細が公開されていないソフト内のインターフェースをホストしたい場合など、DLL内にあるCLSIDを取得したいことがごくまれにある。

LoadTypeLib でDLLを読み込みITypeLibを取得してから、ITypeIfo::GetTypeAttr()を使うことで取得できる。


下の使用例では、Windows標準のシェル関連DLL「shdocvw.dll」を読み込み、GUIDのCLSIDからプログラムIDを取得、出力した。
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;
}

プロジェクトファイルをダウンロード


カテゴリー「その他」 のエントリー