在Visual Studio 2015中,如果我创建一个"类库" C#项目然后添加对自定义COM DLL(使用VB6创建)的引用, VS将自动添加所有(?)VB6 DLL依赖的COM引用。
它是如何做到的?它如何静态地弄清楚这些引用是什么?
注意 - 我们的VB6 DLL使用"早期绑定",但即使仍然没有像传统的" C"风格DLL。
答案 0 :(得分:6)
您实际上是在添加对类型库的引用。它作为资源嵌入在DLL中。使用File>时可以看到它打开>文件,选择DLL,打开TYPELIB节点。它与.NET程序集中的元数据起着完全相同的作用,列出了公开的接口和类的类型定义。它具有二进制格式,您可以使用OleView.exe实用程序对其进行反编译。
并且还具有依赖项信息,注册表有助于查找此类依赖类型库(HKLM \ Software \ Wow6432Node \ Classes \ Typelib键)。与GAC在.NET中扮演的角色大致相同。 COM并不像.NET那样与每个人都假设不同:) CLR的第一个版本是由Microsoft的COM +组创建的。消除与COM相关的注册和DLL Hell问题是todo列表的顶部。
类型库并非完全遗留下来,它们仍然在全新的WinRT(又名UWP,又名现代UI)中扮演关键角色。这是基于COM的核心,非常隐蔽。但由于限制,旧格式已退役,取而代之的是.winmd格式。这与.NET元数据格式完全相同。任何.NET反编译器都可以显示其内容。
答案 1 :(得分:1)
Visual Studio类型库导入程序追逐类型库依赖项的原因是收集类型信息以映射到.NET。
类型库没有直接依赖关系信息。所以这是一个非常好的问题:如何跟踪类型库依赖关系?
检测类型库依赖关系的唯一可行方法是引用声明类型库的类型。
例如,如果您的类型库在方法的签名中引用IXMLDOMDocument
,它将被记录在类型信息记录中。
您可以抓取类型库,方法是加载一个类型库,从中获取ITypeLib
并递归枚举ITypeInfo
。
你最终会看到这条记录。然后,您可以通过ITypeInfo::GetContainingTypeLib
获取包含类型库ID的类型。如果它引用另一个类型库,则会找到依赖项。
爬虫程序可以一直跟踪依赖项,直到它不再需要加载类型库为止。
您不必抓取每个类型库的每种类型来查找严格必要的类型集,但类型库导入器的工作是将类型库信息镜像到.NET类型信息和元数据程序集,因此它完全导入类型库。它更易于实现,解释/理解它正在做什么,并且输出可以在根类型库的上下文之外重用。
如果您没有使用早期绑定,那么您的类型库会提及IDispatch
,IUnknown
和/或VARIANT
,这将导致无法检测到任何依赖关系。
您可以在隔离的应用程序中使用无注册的COM来排除依赖关系,但它仍然不必是正确的依赖关系树,例如您可以在一个清单中声明所有依赖项。
请记住类型库!= DLL。类型库可以作为资源嵌入DLL或其自己的TLB文件中。
所以,整个讨论是关于类型依赖关系,而不是类/组件或其他运行时依赖关系。
答案 2 :(得分:0)
我认为它实际上并不是静态分析所有依赖项。
我认为它只是添加COM引用,它们是DLL的公共API的一部分。根据我的理解,这些在类型库中是明显可见的,这是DLL的一部分。
可能忽略在内部使用但不在公共接口中使用的其他依赖项。