2017-05-09 3 views
0

Je convertis une application pour utiliser COM sans inscription. Il y a quelques dll COM tierces qui auraient normalement besoin de regsvr32. J'ai testé que je peux créer des objets à partir de ces dlls tiers en faisant un manifeste côte à côte. J'ai utilisé la visionneuse OLE/COM intégrée à Windows pour obtenir cette information. Cependant, je voudrais faire un programme qui pourrait le faire pour moi manuellement, car ces bibliothèques tierces ont beaucoup de classes que je dois mettre dans le manifeste.Existe-t-il un moyen d'afficher les entrées COM en parcourant un fichier TLB dans .NET?

Est-ce que quelqu'un connaît un moyen de parcourir par programme une bibliothèque de types?

+0

Il n'est pas très clair pourquoi vous voulez faire cela à la dure. Réglez simplement Isolated = True dans la fenêtre Propriétés pour la référence et tout est automagique à partir de là. Ré-inventer cette fonctionnalité, eh bien, aïe. Gardez à l'esprit que la bibliothèque de types n'est pas suffisante, vous ne savez rien sur le proxy/stub pour le composant. Lisez la bibliothèque de types avec LoadTypeLib(). –

+0

Je ne fais pas cela à partir d'un projet .NET – matrixugly

+0

Pas grand-chose à utiliser les balises [C#] et [.net] alors, n'est-ce pas? Toujours le moyen le plus simple de générer le fichier .manifest souhaité. –

Répondre

1

J'ai pris le conseil de Hans et j'ai utilisé LoadTypeLib.

Pour ceux qui recherchent des exemples de code, ce devrait être un excellent point de départ. Je l'ai écrit ce matin et j'ai pu obtenir le xml dont j'avais besoin. Pardonnez-moi de ne pas avoir libéré les objets! Je n'ai pas le temps d'étoffer complètement le reste de cette réponse en ce moment. Les modifications sont les bienvenues.

[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; 
    } 
}