Учитывая COM DLL, извлеките CLSID всех классов и соответствующее имя интерфейса

Мой вопрос похож на Получение CLSID для файла DLL? , я думаю.

У меня есть каталог с некоторыми библиотеками DLL, каждая из которых реализует один или несколько COM-интерфейсов. Я бы хотел получить:

1) Имя каждого интерфейса 2) CLSID класса, реализующего интерфейс

для каждой DLL. Важно, чтобы все можно было сделать программно (так что я не могу использовать какой-то браузер COM и вручную искать эту информацию).

Позже я буду искать CLSID по имени интерфейса и вызывать некоторые методы с помощью IDispatch.

Одна альтернатива, кажется, сканирование реестра, пытаясь сопоставить тип, интерфейс и GUID класса и имя файла .dll. Но это кажется медленным и ненадежным.

Есть ли у кого-нибудь четкое решение этой проблемы?

РЕДАКТИРОВАТЬ:

С ответом Бена Фойгта я пришел со следующим кодом, который соответствует моим потребностям:

ITypeLib *typelib;
ITypeInfo *typeinfo;
LoadTypeLibEx(_T("c:\\mydir\\mycom1"), REGKIND_NONE, &typelib);
for (UINT i = 0;i < typelib->GetTypeInfoCount();++i) {
    TYPEKIND typekind;
    typelib->GetTypeInfoType(i, &typekind);
    if (typekind == TKIND_COCLASS) {
        // class!
        CComBSTR className;
        TYPEATTR *typeattr;
        typelib->GetTypeInfo(i, &typeinfo);
        typeinfo->GetDocumentation(MEMBERID_NIL, &className, NULL, NULL, NULL);
        typeinfo->GetTypeAttr(&typeattr);
        GUID classGUID = typeattr->guid;
        for (UINT j = 0;j < typeattr->cImplTypes;++j) {
            // interface!
            CComBSTR interfaceName;
            HREFTYPE hreftype;
            ITypeInfo *classtypeinfo;
            typeinfo->GetRefTypeOfImplType(j, &hreftype);
            typeinfo->GetRefTypeInfo(hreftype, &classtypeinfo);
            classtypeinfo->GetDocumentation(MEMBERID_NIL, &interfaceName, NULL, NULL, NULL);
            // associate interfaceName with classGUID here
        }
    }
}

7
задан Community 23 May 2017 в 12:08
поделиться