Есть ли способ просмотреть записи COM путем обхода файла TLB в.NET?
Я конвертирую приложение для использования бесплатной регистрации COM. Есть несколько сторонних COM-библиотек, в которых обычно вызывается regsvr32. Я проверил, что я могу создавать объекты из этих сторонних dll, создавая параллельный манифест.
Я использовал OLE/COM Viewer, встроенный в Windows, чтобы получить эту информацию. Однако я хотел бы создать программу, которая могла бы сделать это для меня вручную, так как в этих сторонних библиотеках есть много классов, которые мне нужно добавить в манифест.
Кто-нибудь знает способ программно пройти через библиотеку типов?
1 ответ
Я воспользовался советом Ганса и использовал LoadTypeLib.
Для тех, кто ищет пример кода, это должно стать отличной отправной точкой. Я написал это сегодня утром и смог получить XML, который мне был нужен.
Прости меня за то, что не отпускаешь предметы! У меня нет времени, чтобы полностью раскрыть остальную часть этого ответа прямо сейчас. Изменения приветствуются.
[DllImport("oleaut32.dll", PreserveSig = false)]
public static extern ITypeLib LoadTypeLib([In, MarshalAs(UnmanagedType.LPWStr)] string typelib);
public static void ParseTypeLib(string filePath)
{
string fileNameOnly = Path.GetFileNameWithoutExtension(filePath);
ITypeLib typeLib = LoadTypeLib(filePath);
int count = typeLib.GetTypeInfoCount();
IntPtr ipLibAtt = IntPtr.Zero;
typeLib.GetLibAttr(out ipLibAtt);
var typeLibAttr = (System.Runtime.InteropServices.ComTypes.TYPELIBATTR)
Marshal.PtrToStructure(ipLibAtt, typeof(System.Runtime.InteropServices.ComTypes.TYPELIBATTR));
Guid tlbId = typeLibAttr.guid;
for(int i=0; i< count; i++)
{
ITypeInfo typeInfo = null;
typeLib.GetTypeInfo(i, out typeInfo);
//figure out what guids, typekind, and names of the thing we're dealing with
IntPtr ipTypeAttr = IntPtr.Zero;
typeInfo.GetTypeAttr(out ipTypeAttr);
//unmarshal the pointer into a structure into something we can read
var typeattr = (System.Runtime.InteropServices.ComTypes.TYPEATTR)
Marshal.PtrToStructure(ipTypeAttr, typeof(System.Runtime.InteropServices.ComTypes.TYPEATTR));
System.Runtime.InteropServices.ComTypes.TYPEKIND typeKind = typeattr.typekind;
Guid typeId = typeattr.guid;
//get the name of the type
string strName, strDocString, strHelpFile;
int dwHelpContext;
typeLib.GetDocumentation(i, out strName, out strDocString, out dwHelpContext, out strHelpFile);
if (typeKind == System.Runtime.InteropServices.ComTypes.TYPEKIND.TKIND_COCLASS)
{
string xmlComClassFormat = "<comClass clsid=\"{0}\" tlbid=\"{1}\" description=\"{2}\" progid=\"{3}.{4}\"></comClass>";
string comClassXml = String.Format(xmlComClassFormat,
typeId.ToString("B").ToUpper(),
tlbId.ToString("B").ToUpper(),
strDocString,
fileNameOnly, strName
);
//Debug.WriteLine(comClassXml);
}
else if(typeKind == System.Runtime.InteropServices.ComTypes.TYPEKIND.TKIND_INTERFACE)
{
string xmlProxyStubFormat = "<comInterfaceExternalProxyStub name=\"{0}\" iid=\"{1}\" tlbid=\"{2}\" proxyStubClsid32=\"{3}\"></comInterfaceExternalProxyStub>";
string proxyStubXml = String.Format(xmlProxyStubFormat,
strName,
typeId.ToString("B").ToUpper(),
tlbId.ToString("B").ToUpper(),
"{00020424-0000-0000-C000-000000000046}"
);
//Debug.WriteLine(proxyStubXml);
}
}
return;
}
}