从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

你可能感兴趣的:(com)