0
我正在转换应用程序以使用注册免费COM。有几个第三方COM DLL通常会有regsvr32调用它们。我测试了我可以通过制作并排清单来从这些第三方dll创建对象。有没有办法通过在.NET中遍历TLB文件来查看COM条目?
我使用Windows内置的OLE/COM查看器来获取此信息。不过,我想制作一个可以手动执行此操作的程序,因为这些第三方库有许多需要放在清单中的类。
有谁知道一种以编程方式遍历类型库的方法吗?
我正在转换应用程序以使用注册免费COM。有几个第三方COM DLL通常会有regsvr32调用它们。我测试了我可以通过制作并排清单来从这些第三方dll创建对象。有没有办法通过在.NET中遍历TLB文件来查看COM条目?
我使用Windows内置的OLE/COM查看器来获取此信息。不过,我想制作一个可以手动执行此操作的程序,因为这些第三方库有许多需要放在清单中的类。
有谁知道一种以编程方式遍历类型库的方法吗?
我接受了Hans的建议并使用了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;
}
}
这是不是很清楚你为什么要这样做的困难。只需在属性窗口中为参考设置为Isolated = True,并且从那里开始就是自动的。重新发明这个功能,呃。请记住,类型库是不够的,你不知道组件的代理/存根。用LoadTypeLib()读取类型库。 –
我不是在.NET项目中这样做的 – matrixugly
那么在使用[c#]和[.net]标签的时候没有太多意义,是吗?仍然是生成你想要的.manifest文件的最简单的方法。 –