Как получить Интерфейсный идентификатор COM-класса так, чтобы он мог быть передан CoCreateInstance?

Я хочу к programaticly, получают Интерфейсный идентификатор для любого класса так, чтобы я мог передать его 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();
10
задан akira 1 November 2012 в 10:25
поделиться

3 ответа

Вам нужно заранее знать, какой интерфейс вы запрашиваете. Это вы получаете из спецификаций продукта, из файлов заголовков SDK или можете импортировать TLB COM-объекта в свой проект.

Самый простой способ - использовать #import

3
ответ дан 4 December 2019 в 02:25
поделиться

Необходимо заранее знать, какой интерфейс требуется. Это можно получить из спецификаций продукта, из файлов заголовков SDK или можно импортировать TLB COM-объекта в проект.

самый простой способ - использовать # import

-121--3176599-

Хорошо, у меня есть новый способ сделать это, который может работать немного лучше для меня. Это вариант моего комментария к ответу Майкла Петротты:

Но это дает мне идею иметь несколько пользователей и выбрать последовательность соединения на лету.

То, что я буду делать, это иметь только одного пользователя для выполнения этих запросов, но я поменяю строку соединения на лету, чтобы указать правильный начальный каталог.

-121--4145162-

Вы уже знаете это. Это будет тип вывода времени компиляции , который функция должна сохранить в переменной pInterface , которую она присвоила.

Другими словами, какой тип интерфейса вы собираетесь рассматривать как созданный объект? Какие методы интерфейса вы собираетесь вызвать для него?

Тип, который вы получаете от CLSIDFromProgID , может быть любой версией интерфейса, включая тот, который даже не существовал на момент компиляции кода. Обычно можно предположить, что любая версия, доступная во время выполнения, также поддерживает меньшую версию, о которой известно во время компиляции. Вы попросите операционную систему создать экземпляр последней версии, но затем также попросите ее вернуть ссылку на интерфейс меньшей версии, который вы умеете обрабатывать.

Функция вызывает QuureInterface для объекта, используя запрошенный тип, примерно так:

obj->QueryInterface(riid, pInterface);

Если у вас нет ничего более конкретного для запроса, просто используйте IUnknown .

3
ответ дан 4 December 2019 в 02:25
поделиться

платформа SDK распространяется с исходным кодом утилиты OleView, которая содержит довольно хороший пример построения дерева всех возможных CLSID и их имен

2
ответ дан 4 December 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: