My question is similar to Getting CLSID for a DLL file?, I think.
I have a directory with some DLLs, each one implementing one or more COM interfaces. I would like to get:
1) Each interface name 2) The CLSID of the class implementing the interface
For each DLL. It's important that everything can be done programatically (So I can't use some sort of COM browser and manually look up for that information).
Later I will lookup the CLSID given the interface name and call some methods using IDispatch.
One alternative seems to be scanning the registry trying to match the type, interface and class GUID and the .dll filename. But that seems to be slow and not robust.
Does someone has a clear solution to this problem?
EDIT:
With the response of Ben Voigt, I came with the following code which suit my needs:
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
}
}
}
DllGetClassObject
might have undesirable side effects, so I don't recommend this. Also, it's entirely possible to have a combination of public CLSIDs and private ones. Since the DLL is loaded by creation of a public type, there's no need to ever load the DLL outside the COM mechanisms. – Outleap