2017-05-09 30 views
0

我正在转换应用程序以使用注册免费COM。有几个第三方COM DLL通常会有regsvr32调用它们。我测试了我可以通过制作并排清单来从这些第三方dll创建对象。有没有办法通过在.NET中遍历TLB文件来查看COM条目?

我使用Windows内置的OLE/COM查看器来获取此信息。不过,我想制作一个可以手动执行此操作的程序,因为这些第三方库有许多需要放在清单中的类。

有谁知道一种以编程方式遍历类型库的方法吗?

+0

这是不是很清楚你为什么要这样做的困难。只需在属性窗口中为参考设置为Isolated = True,并且从那里开始就是自动的。重新发明这个功能,呃。请记住,类型库是不够的,你不知道组件的代理/存根。用LoadTypeLib()读取类型库。 –

+0

我不是在.NET项目中这样做的 – matrixugly

+0

那么在使用[c#]和[.net]标签的时候没有太多意义,是吗?仍然是生成你想要的.manifest文件的最简单的方法。 –

回答

1

我接受了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; 
    } 
} 
相关问题