首页 > 解决方案 > 关于 COM .net 程序集、regasm、dll、tlb 和 guids 的几个简短问题

问题描述

所有问题都与 .net framework 2.0 中的一个 .net 项目 dll 有关,该 dll 将自身暴露为 COM。

1) 如果我们没有在源代码(类型库、类、接口)中指定任何 GUID,谁在生成 GUID?编译器还是 regasm?

2) GUID 值存在于 dll、tlb 中还是两个文件中?

3) 任何具有相同源代码的开发人员都会在她构建或运行 regasm 的机器上独立生成相同的 GUID?

4) 如果我运行 regasm 传递现有的 dll 和 tlb 文件,如果 dll 和 tlb 不匹配会发生什么?Regasm 使用最新的元素和 GUID 重新生成 tlb 文件?还是用当前的 tlb 文件注册 TypeLib?

5) 设置 dll 和 tlb 参数运行 regasm 有什么意义?Tlb 文件是您部署的内容的一部分,或者最好只部署 dll 并让 regasm 动态生成 tlb?

6)最后一个问题,真的需要 tlb 吗?有一个 tlb 文件有什么意义?不是所有的信息都已经在注册表中了吗?它提供了哪些额外信息?

7) 注销 regasm 时,我们需要提供什么?dll?TLB?两个都?如果 dll(或 tlb)与现有的 reg 条目不匹配会怎样?如果已经使用 tlb 选项注册,但我只使用 dll 运行 regasm unregister,它也会删除 TypeLyb 条目吗?

8) 关于位数,regasm 也总是会在 SysWow64 下生成条目?Framework64下的regasm和Framework下的regasm一样吗?

标签: comregasm

解决方案


类型库完全等同于 .NET 元数据。它对客户端程序员最有用,它使编译器和 IDE 对您的库更智能。提供自动完成和语法检查,因此他的代码和你的代码不匹配的可能性很小。注册步骤是必要的,这样您的文件就可以被找回。类型库通常作为资源嵌入到 DLL 本身中,例如 .NET 元数据,但 .NET 构建模型并不容易做到这一点。客户端编译器使用类型库信息来生成适当的 COM 调用。Guid 很重要,因为这是客户端编译器需要使用的,标识符名称不起作用。有一种方法可以使用名称来使用“后期绑定”,这与 .NET 中的反射完全等效,但不涉及类型库。

谁在生成 GUID?

CLR 可以。每个 .NET 接口或类都有一个,无论它是否为 [ComVisible(true)]。也通过 Type.GUID 属性公开。如果您没有在类型上使用 [Guid] 属性,那么它会运行一个算法来生成使用类型声明作为输入的 Guid。或者换句话说,如果您对类型进行任何更改,那么您可以确定 Guid 将具有不同的值。这是你永远不应该使用 [Guid] 属性的基本原因,除非你必须创建一个精确的插入替换并且不能重新编译客户端代码。TLBID 来自于您在创建项目时自动生成的 AssemblyInfo.cs 文件。

在 dll 中,在 tlb 中还是在两个文件中?

它仅在您使用 [Guid] 属性时存在于 DLL 中,但通常它是在运行时生成的,如上所述。它始终存在于类型库中,这就是客户端编译器知道创建类的对象并使用其接口的方式。

将生成完全相同的 GUID

是的,只有类型声明起作用。

如果我运行 regasm 传递现有的 dll 和 tlb 文件

Regasm 只能根据 /tlb 选项的要求创建一个类型库,它不能采用现有的类型库。否则,它的作用与 Tlbexp.exe 完全相同,使用反射枚举程序集中的类型以查找 [ComVisible(true)] 并生成匹配的类型库声明。它所做的额外事情是将类型库的注册表项写入 HKLM/Software/Classes/Typelib。所以客户端 IDE 可以找到它。

设置 dll 和 tlb 参数运行 regasm 有什么意义?

“dll参数”可能意味着没有真正的想法。如上所述,使用 /tlb 生成类型库。是否部署类型库取决于它的使用情况,如果您不提供客户端代码,那么您应该始终部署它,以便客户端程序员可以使用它。类型库的其他用法是本文的主题。如果您不确定客户端程序员将如何使用您的代码,请始终进行部署。

不是所有的信息都已经在注册表中了吗?

注册表中的内容是有限的,只有足够的信息才能找到类型库文件。您的接口的描述、它们的方法签名、guid 和工厂函数所需的 CLSID 都在类型库中。

注销 regasm 时,我们需要提供什么?

与注册完全相同,您只需添加/取消注册。如果您以前使用过 /tlb,您还必须提供它,以便可以删除 TypeLib 注册表项。当您忙于开发和测试库时,自动执行此操作非常重要,因为 guid 通常是自动生成的,您可能会在注册表中产生大量垃圾。当您忘记运行 Regasm 时,还会让人头疼。项目 > 属性 > 构建选项卡,“注册 COM 互操作”复选框。但缺点是您必须运行 VS 提升才能写入注册表。

regasm 也总是会在 SysWow64 下生成条目吗?

SysWow64 没有任何作用,请始终避免部署到 c:\windows。但是,是的,位数确实很重要,注册表的结构使得 64 位应用程序不会意外地在 32 位库中创建对象并死于丑陋的异常。反之亦然。32 位客户端应用程序将从 HKLM/Software/WOW6432Node 读取注册表项,您只能在使用 32 位版本的 Regasm 时获取您的注册表项。值得注意的是,鉴于 C# 代码可以在任何平台上运行,运行两种 Regasm 风格通常都很好。


推荐阅读