【问题标题】:Importing nested COM references导入嵌套的 COM 引用
【发布时间】:2017-01-15 02:42:54
【问题描述】:

在 Visual Studio 2015 中,如果我创建“类库”C# 项目,然后添加对自定义 COM DLL(使用 VB6 创建)的引用,VS 也会自动添加所有(?)COM 引用VB6 DLL 依赖于

它是如何做到的?它如何静态地找出那些引用是什么?

注意——我们的 VB6 DLL 使用“早期绑定”,但仍然没有像在传统“C”样式 DLL 中看到的那样用于 COM 项的导入表。

【问题讨论】:

    标签: c# visual-studio com vb6


    【解决方案1】:

    您实际上是在添加对类型库的引用。它作为资源嵌入在 DLL 中。您可以在使用 File > Open > File 时看到它,选择 DLL,打开 TYPELIB 节点。它在 .NET 程序集中扮演与元数据完全相同的角色,列出公开的接口和类的类型定义。它具有二进制格式,您可以使用 OleView.exe 实用程序对其进行反编译。

    并且还有依赖信息,注册表有助于找到这些依赖类型库(HKLM\Software\Wow6432Node\Classes\Typelib 键)。 GAC 在 .NET 中扮演的角色大致相同。 COM 与 .NET 并没有大家想象的那么不同 :) CLR 的第一个版本是由 Microsoft 的 COM+ 小组创建的。消除与 COM 相关的注册和 DLL Hell 问题是待办事项列表的首要任务。

    类型库并不完全是遗留的,它们仍然在全新的 WinRT(又名 UWP,又名 Modern UI)中发挥着关键作用。它的核心是基于 COM 的,隐藏得非常好。但是由于限制,旧格式已被淘汰,取而代之的是 .winmd 格式。这与 .NET 元数据格式完全相同。任何 .NET 反编译器都可以显示它们的内容。

    【讨论】:

    • 并且还有依赖信息,注册表有助于找到这样的依赖类型库(HKLM\Software\Wow6432Node\Classes\Typelib 键) – 这到底是哪里依赖信息?
    • 在类型库中。用Oleview.exe看一下,importlib()语句。
    • 嗯,看来TLB确实引用了导入的库。但是,tlbimp.exe & co。似乎只遍历来自ITypeLib 的可用数据,而后者又为包含更多ITypeInfos(例如继承、方法参数、方法返回类型或字段类型)的接口、结构等返回ITypeInfo,这些可能是包含在其他类型库中,主要是通过ITypeInfo::GetContainingTypeLib
    • 我在 tlbodl.cpp 中所说的 OleView.exe 的最新源代码: 源中很可能有“importlib()”语句。虽然似乎可以识别它们,但它并不重要,目前不受支持。 另外:TODO:对导入库中定义的任何引用类型的所有类型信息进行 Grovel 我认为 OleView 目前采用的是当时尚未完成的方法。
    • 好的,我已经看到了一些带有 OleView 的类型库,它生成的 importlib 语句反映了当前注册的类型库,尽管 LIBID 似乎来自类型库的内部而没有在HKCR\Interface 中的注册表。
    【解决方案2】:

    Visual Studio 类型库导入器追逐类型库依赖关系的原因是收集类型信息以映射到 .NET。

    类型库没有直接的依赖信息。所以这是一个非常好的问题:如何跟踪类型库依赖关系?

    检测类型库依赖关系的唯一可行方法是引用声明声明类型库的类型。

    例如,如果您的类型库在方法的签名中引用IXMLDOMDocument,它将被记录在类型信息记录中。

    您可以爬取类型库,方法是加载一个类型库,从中获取 ITypeLib 并递归枚举 ITypeInfos。

    您最终会看到这条记录。然后,您可以通过ITypeInfo::GetContainingTypeLib 获取该类型的包含类型库ID。如果它引用了另一个类型库,那么你找到了一个依赖项。

    爬虫可能会一直跟踪依赖关系,直到没有更多类型库要加载。

    您不必爬取每个类型库的每个类型来找到严格必要的类型集,但是类型库导入器的工作是将类型库信息镜像到 .NET 类型信息和元数据程序集,因此它完全导入类型库。它更易于实现、解释/理解它在做什么,并且输出可在根类型库的上下文之外重用。

    如果您不使用早期绑定,您的类型库将改为提及IDispatchIUnknown 和/或VARIANT,这将导致无法检测到任何依赖关系。

    您可以在孤立的应用程序中使用免注册 COM 来整理依赖关系,但它仍然不必是正确的依赖关系树,例如您可以在一个清单中声明所有依赖项。

    记住那个类型库!= DLL。类型库可以作为资源嵌入到 DLL 或它自己的 TLB 文件中。

    所以,整个讨论都是关于 type 依赖项,而不是 class/component 或其他运行时依赖项。

    【讨论】:

      【解决方案3】:

      我不认为它实际上是在静态分析所有依赖关系。

      我认为它只是添加 COM 引用,它们是 DLL 的公共 API 的一部分。据我了解,这些在作为 DLL 一部分的 typelib 中是显而易见的。

      可能会忽略其他在内部使用但不在公共接口中的依赖项。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-05
        • 2013-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多