首页 > 代码库 > 从tlb,ocx,dll类型库中提取com组件的CLSID

从tlb,ocx,dll类型库中提取com组件的CLSID

最近在做项目的时候遇到了这个问题。

项目需要动态根据添加com组件,获取组件的某个接口函数。

 

一般情况下,我们创建com组件的方法是根据它的CLSID号,获得相应的interface,然后通过返回的指针调用相应的接口函数。如下:

CoInitialize( NULL );IpTest* pMask = NULL;HRESULT hr = CoCreateInstance( CLSID_TEST, NULL, CLSCTX_INPROC, IID_ITEST, (LPVOID*)&IpTest );if( !SUCCEEDED(hr) ){    AfxMessageBox( _T("com组件创建失败,请检查其是否安装并注册") );    return 0;}IpTest->SomeFunc();//调用相应的接口函数IpTest->Release();CoUninitialize();

 

现在项目要根据输入tlb文件获得对应com组件的CLSID,然后调用CoCreateInstance()函数,传给它刚刚读取的CLSID。

百度,google了半天才找到了解决方案,特此记录下来。

稍微简单封装成函数.

#include <windows.h>#include <comdef.h>
ITypeLib *pTypeLib = NULL;ITypeInfo *pTypeInfo = NULL;TYPEATTR *pTypeAttr = NULL;void Cleanup();GUID getCLSIDFromFile(const CString &strFileName)throw(std::runtime_error);//strFileName--输入tlb,ocx文件路径GUID getCLSIDFromFile(const CString &strFileName)throw(std::runtime_error){    _bstr_t str;    HRESULT hr;    TCHAR* pwszProgID = NULL;        hr = LoadTypeLib(strFileName,&pTypeLib);//加载类型库信息    if ( FAILED(hr))     {        Cleanup();         return GUID();    }    UINT iCount = pTypeLib->GetTypeInfoCount(); //获取类型数量    for (int i=0; i < iCount ; i++)     {        if (FAILED(hr = (pTypeLib->GetTypeInfo(i, &pTypeInfo))))//获取类型说明信息        {            Cleanup();            throw runtime_error("输入文件不包含相关com组件接口");            return GUID();        }        if (FAILED(hr = (pTypeInfo->GetTypeAttr(&pTypeAttr))))//获取类型属性        {            Cleanup();            throw runtime_error("输入文件不包含相关com组件接口");            return GUID();        }                if (TKIND_COCLASS == pTypeAttr->typekind)//判断是否为组件接口            return pTypeAttr->guid;        pTypeInfo->ReleaseTypeAttr(pTypeAttr);        pTypeInfo->Release();    }    pTypeLib->Release();    pTypeLib = NULL;    throw runtime_error("输入文件不包含相关com组件接口");    return GUID();}void Cleanup(){    if (pTypeAttr)        pTypeInfo->ReleaseTypeAttr(pTypeAttr);    if (pTypeInfo)        pTypeInfo->Release();    pTypeAttr = NULL;    pTypeInfo = NULL;}

使用的时候直接传入tlb,ocx,dll文件路径给getCLSIDFromFile()函数,函数返回值即对应com组件的CLSID;

获得了组件的CLSID,就可以按照常规方法访问组件对应的接口了。

 

当然如果知道了对应组件的ProgID,可以用

HRESULT CLSIDFromProgID(  LPCOLESTR lpszProgID,  //Pointer to the ProgID  LPCLSID pclsid         //Pointer to the CLSID);
传入对应ProgID字符串,返回相应CLSID;

 

 

参考链接:http://support.microsoft.com/kb/286340/zh-cn