如何检索COM类的接口ID,以便将其传递给CoCreateInstance?

时间:2010-02-22 19:13:52

标签: c++ windows com

我想以编程方式检索任何类的接口ID,以便将其传递给CoCreateInstance。非常感谢任何帮助!!

请参阅下面的“如何获取此信息”:

HRESULT hResult;
CLSID ClassID;
void *pInterface;

if(!(hResult = SUCCEEDED(CoInitialize(NULL))))
{
    return 1;
}

if(S_OK == CLSIDFromProgID(OLESTR("Scripting.FileSystemObject"), &ClassID))
{
    hResult = CoCreateInstance(ClassID, NULL, CLSCTX_INPROC_SERVER,
        <<How Do I Get This?>>, (LPVOID *)&pInterface);
}

CoUninitialize();

编辑:感谢所有帮助,现在似乎完美无缺! :

HRESULT hResult;
CLSID ClassID;
IClassFactory *pClf;
void *pVdb;

if(!(hResult = SUCCEEDED(CoInitialize(NULL))))
{
    return 1;
}

if(SUCCEEDED(CLSIDFromProgID(OLESTR("Scripting.FileSystemObject"), &ClassID))
{
    IDispatch *pDispatch;

    if(SUCCEEDED(CoCreateInstance(ClassID, NULL, CLSCTX_INPROC_SERVER,
            IID_IDispatch, (void **)&pDispatch))
    {
        OLECHAR *sMember = L"FileExists";

        DISPID idFileExists;

        if(SUCCEEDED(pDispatch->GetIDsOfNames(
                IID_NULL, &sMember, 1, LOCALE_SYSTEM_DEFAULT, &idFileExists))
        {
            unsigned int puArgErr = 0;

            VARIANT VarResult;
            EXCEPINFO pExcepInfo;

            VariantInit(&VarResult); 
            VariantInit(&pExcepInfo); 

            DISPPARAMS pParams;
            memset(&pParams, 0, sizeof(DISPPARAMS)); 
            pParams.cArgs = 1; 

            VARIANT Arguments[1];
            VariantInit(&Arguments[0]); 

            pParams.rgvarg = Arguments; 
            pParams.cNamedArgs = 0;
            pParams.rgvarg[0].vt = VT_BSTR;
            pParams.rgvarg[0].bstrVal = SysAllocString(L"C:\\Test.txt");

            hResult = pDispatch->Invoke(  
                idFileExists,
                IID_NULL,
                LOCALE_SYSTEM_DEFAULT,
                DISPATCH_METHOD,
                &pParams,
                &VarResult,
                &pExcepInfo,
                &puArgErr
            );

            SysFreeString(pParams.rgvarg[0].bstrVal);

            printf("File Exists? %d\n", abs(VarResult.boolVal));
        }

        pDispatch->Release();
    }
}

CoUninitialize();

3 个答案:

答案 0 :(得分:3)

您需要提前了解您要求的界面。您可以从产品规范,SDK头文件中获取,也可以将COM对象的TLB导入到项目中。

最简单的方法是使用#import

答案 1 :(得分:3)

你已经知道了。您希望函数存储在您提供的pInterface变量中,这将是编译时输出类型

换句话说,您要将您创建的对象视为哪种接口类型?你打算在哪个界面上调用它?

CLSIDFromProgID获得的类型可能是该界面的任何版本,包括在编译代码时甚至不存在的版本。您通常可以假设在运行时可用的任何版本也支持在编译时您知道的一些较小版本。您要求操作系统实例化最新版本的实例,但之后您还要求它返回对较小版本界面的引用 - 您知道如何处理的界面。

该函数使用您请求的类型为您调用对象QueryInterface,如下所示:

obj->QueryInterface(riid, pInterface);

如果您没有更具体的要求,请使用IUnknown

答案 2 :(得分:2)

平台SDK与OleView实用程序的源代码一起分发,包含了构建所有可能的CLSID及其名称的树的非常好的示例