2017-05-09 18 views
0

등록 무료 COM을 사용하도록 응용 프로그램을 변환 중입니다. 일반적으로 regsvr32가 호출되는 타사 COM DLL이 몇 가지 있습니다. 필자는 side-by-side manifest를 만들어 써드 파티 DLL로부터 객체를 생성 할 수 있는지 테스트했다..NET에서 TLB 파일을 통과하여 COM 항목을 보는 방법이 있습니까?

이 정보를 얻기 위해 Windows에 내장 된 OLE/COM 뷰어를 사용했습니다. 그러나 제 3 자 라이브러리에는 매니페스트에 넣어야 할 많은 클래스가 있으므로 수동으로이 작업을 수행 할 수있는 프로그램을 만들고 싶습니다.

누구든지 프로그래밍 방식으로 형식 라이브러리를 탐색하는 방법을 알고 있습니까?

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