La mia domanda è simile a Getting CLSID for a DLL file?, penso.Data una DLL COM, estrarre tutte le classi CLSID e il nome dell'interfaccia corrispondente
Ho una directory con alcune DLL, ognuna delle quali implementa una o più interfacce COM. Vorrei ottenere:
1) Ogni nome dell'interfaccia 2) Il CLSID della classe che implementa l'interfaccia
Per ogni DLL. È importante che tutto sia programmabile (quindi non posso usare una sorta di browser COM e cercare manualmente tali informazioni).
Successivamente cercherò il CLSID dato il nome dell'interfaccia e chiamerò alcuni metodi usando IDispatch.
Un'alternativa sembra essere la scansione del registro cercando di corrispondere al tipo, all'interfaccia e al GUID della classe e al nome file .dll. Ma sembra essere lento e non robusto.
Qualcuno ha una soluzione chiara a questo problema?
EDIT:
Con la risposta di Ben Voigt, sono venuto con il seguente codice che più adatto alle mie esigenze:
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' potrebbe avere effetti collaterali indesiderati, in modo da non consigliare questo. Inoltre, è del tutto possibile avere una combinazione di CLSID pubblici e privati. Poiché la DLL viene caricata con la creazione di un tipo pubblico, non è necessario caricare la DLL all'esterno dei meccanismi COM. –
Bene, la * massima * analisi forense comporterebbe il disassemblaggio della DLL e il codice di DllGetClassObject(). Nell'implementazione tipica (leggi: quella ATL) ci sarebbe una struttura di dati globale che elenca ordinatamente tutti i CLSID in un unico posto. Riesco a malapena a immaginare una DLL COM in cui il set di coclassi supportate è condizionale. –
Dipende da quanto è subdolo lo schema di licenza. Sicuramente posso immaginare un requisito per istanziare un oggetto gestore di licenze e usarlo prima che qualsiasi altra classe possa essere istanziata, la domanda è se l'errore dal tentativo di creare oggetti senza una licenza è "Non so quell'oggetto" o "Ho provato per creare quell'oggetto ma non è riuscito " –