关于 COM .net 程序集、regasm、dll、tlb 和 guid 的几个简短问题
Several short questions about COM .net assemblies, regasm, dll, tlb and 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 参数的情况下 运行ning regasm 有什么意义?
Tlb 文件是您部署的一部分,或者最好只部署 dll 并让 regasm 动态生成 tlb?
6) 最后一个问题,真的需要 tlb 吗?有一个 tlb 文件有什么意义?是不是所有的信息都已经在注册表中了?它提供了哪些额外信息?
7) 注销regasm时,我们需要提供什么? dll? Tlb?两个都?如果 dll(或 tlb)与现有的 reg 条目不匹配会怎样?如果已经使用 tlb 选项注册但我 运行 regasm 注销 dll 仅它会删除 TypeLyb 条目吗?
8) 关于位数,regasm 也总是会在 SysWow64 下生成条目吗? Framework64下的regasm和Framework下的一样吗?
类型库完全等同于 .NET 元数据。它对客户端程序员最有用,它使编译器和 IDE 对你的库变得聪明。提供自动完成和语法检查,这样他的代码和你的代码不匹配的可能性就会降到最低。注册步骤是必要的,以便可以找回您的文件。类型库通常作为资源嵌入到 DLL 本身中,就像 .NET 元数据一样,但 .NET 构建模型并不容易做到这一点。客户端编译器使用类型库信息生成适当的 COM 调用。 Guids 很重要,因为这是客户端编译器需要使用的东西,标识符名称不起作用。有一种使用名称的方法 "late binding",与 .NET 中的反射完全等效,但不涉及类型库。
who is generating the GUIDs?
CLR 可以。每个 .NET 接口或 class 都有一个,不管它是否是 [ComVisible(true)]。暴露也通过Type.GUID属性。如果您没有在类型上使用 [Guid] 属性,那么它 运行 是一种生成使用类型声明作为输入的 Guid 的算法。或者换句话说,如果您对类型进行了任何更改,那么您可以确定 Guid 将具有不同的值。这是你永远不应该使用 [Guid] 属性的基本原因,除非你必须创建一个精确的直接替换并且不能重新编译客户端代码。 TLBID 来自创建项目时自动生成的 AssemblyInfo.cs 文件。
in the dll, in the tlb or in both files?
它仅在您使用 [Guid] 属性时存在于 DLL 中,但通常它会在 运行 时生成,如上所述。它始终存在于类型库中,这就是客户端编译器如何知道创建您的 class 对象并使用其接口的方式。
would generate the very same GUIDs
是的,只有类型声明起作用。
If I run regasm passing existing dll and tlb files
Regasm 只能创建 类型库,根据其 /tlb 选项的要求,它不能采用现有类型库。它在其他方面与 Tlbexp.exe 完全相同,使用反射枚举程序集中的类型以找到 [ComVisible(true)] 类型并生成匹配的类型库声明。它所做的额外事情是将类型库的注册表项写入 HKLM/Software/Classes/Typelib。所以客户端IDE可以找回来。
What is the point of running regasm with dll and tlb parameters set?
没有真正的想法 "dll parameter" 可能意味着。如上所述,使用 /tlb 生成类型库。是否部署类型库取决于它的用途,如果您不提供客户端代码,那么您应该始终部署它,以便客户端程序员可以使用它。类型库的其他用法是 this post 的主题。如果您不确定客户端程序员将如何使用您的代码,那么请始终部署。
Is not all the information already in the registry?
注册表中的内容有限,仅够找到类型库文件的信息。您的接口的描述、它们的方法签名、guid 和工厂函数需要的 CLSID 都在类型库中。
When unregistering with regasm, what we need to provide?
和注册完全一样,你只需要添加/unregister。如果您以前使用过 /tlb,则还必须提供它,以便可以删除 TypeLib 注册表项。在您忙于开发和测试库时自动执行此操作可能非常重要,因为 guid 通常是自动生成的,您可能会在注册表中产生大量垃圾。以及当您忘记 运行 Regasm 时令人头疼的难看问题。项目 > 属性 > 构建选项卡,"Register for COM interop" 复选框。但缺点是你必须 运行 VS 提升才能写入注册表。
regasm will always generate entries under SysWow64 too?
SysWow64 不起作用,请始终避免部署到 c:\windows。但是,是的,位数确实很重要,注册表的结构使得 64 位应用程序不会意外地在 32 位库中创建对象并死于丑陋的异常。反之亦然。 32 位客户端应用程序将从 HKLM/Software/WOW6432Node 读取注册表项,您只能在使用 32 位版本的 Regasm 时获取注册表项。值得注意的是,考虑到 C# 代码可以在任何平台上 运行,通常 运行 两种 Regasm 版本都可以。
所有问题都与 .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 参数的情况下 运行ning regasm 有什么意义? Tlb 文件是您部署的一部分,或者最好只部署 dll 并让 regasm 动态生成 tlb?
6) 最后一个问题,真的需要 tlb 吗?有一个 tlb 文件有什么意义?是不是所有的信息都已经在注册表中了?它提供了哪些额外信息?
7) 注销regasm时,我们需要提供什么? dll? Tlb?两个都?如果 dll(或 tlb)与现有的 reg 条目不匹配会怎样?如果已经使用 tlb 选项注册但我 运行 regasm 注销 dll 仅它会删除 TypeLyb 条目吗?
8) 关于位数,regasm 也总是会在 SysWow64 下生成条目吗? Framework64下的regasm和Framework下的一样吗?
类型库完全等同于 .NET 元数据。它对客户端程序员最有用,它使编译器和 IDE 对你的库变得聪明。提供自动完成和语法检查,这样他的代码和你的代码不匹配的可能性就会降到最低。注册步骤是必要的,以便可以找回您的文件。类型库通常作为资源嵌入到 DLL 本身中,就像 .NET 元数据一样,但 .NET 构建模型并不容易做到这一点。客户端编译器使用类型库信息生成适当的 COM 调用。 Guids 很重要,因为这是客户端编译器需要使用的东西,标识符名称不起作用。有一种使用名称的方法 "late binding",与 .NET 中的反射完全等效,但不涉及类型库。
who is generating the GUIDs?
CLR 可以。每个 .NET 接口或 class 都有一个,不管它是否是 [ComVisible(true)]。暴露也通过Type.GUID属性。如果您没有在类型上使用 [Guid] 属性,那么它 运行 是一种生成使用类型声明作为输入的 Guid 的算法。或者换句话说,如果您对类型进行了任何更改,那么您可以确定 Guid 将具有不同的值。这是你永远不应该使用 [Guid] 属性的基本原因,除非你必须创建一个精确的直接替换并且不能重新编译客户端代码。 TLBID 来自创建项目时自动生成的 AssemblyInfo.cs 文件。
in the dll, in the tlb or in both files?
它仅在您使用 [Guid] 属性时存在于 DLL 中,但通常它会在 运行 时生成,如上所述。它始终存在于类型库中,这就是客户端编译器如何知道创建您的 class 对象并使用其接口的方式。
would generate the very same GUIDs
是的,只有类型声明起作用。
If I run regasm passing existing dll and tlb files
Regasm 只能创建 类型库,根据其 /tlb 选项的要求,它不能采用现有类型库。它在其他方面与 Tlbexp.exe 完全相同,使用反射枚举程序集中的类型以找到 [ComVisible(true)] 类型并生成匹配的类型库声明。它所做的额外事情是将类型库的注册表项写入 HKLM/Software/Classes/Typelib。所以客户端IDE可以找回来。
What is the point of running regasm with dll and tlb parameters set?
没有真正的想法 "dll parameter" 可能意味着。如上所述,使用 /tlb 生成类型库。是否部署类型库取决于它的用途,如果您不提供客户端代码,那么您应该始终部署它,以便客户端程序员可以使用它。类型库的其他用法是 this post 的主题。如果您不确定客户端程序员将如何使用您的代码,那么请始终部署。
Is not all the information already in the registry?
注册表中的内容有限,仅够找到类型库文件的信息。您的接口的描述、它们的方法签名、guid 和工厂函数需要的 CLSID 都在类型库中。
When unregistering with regasm, what we need to provide?
和注册完全一样,你只需要添加/unregister。如果您以前使用过 /tlb,则还必须提供它,以便可以删除 TypeLib 注册表项。在您忙于开发和测试库时自动执行此操作可能非常重要,因为 guid 通常是自动生成的,您可能会在注册表中产生大量垃圾。以及当您忘记 运行 Regasm 时令人头疼的难看问题。项目 > 属性 > 构建选项卡,"Register for COM interop" 复选框。但缺点是你必须 运行 VS 提升才能写入注册表。
regasm will always generate entries under SysWow64 too?
SysWow64 不起作用,请始终避免部署到 c:\windows。但是,是的,位数确实很重要,注册表的结构使得 64 位应用程序不会意外地在 32 位库中创建对象并死于丑陋的异常。反之亦然。 32 位客户端应用程序将从 HKLM/Software/WOW6432Node 读取注册表项,您只能在使用 32 位版本的 Regasm 时获取注册表项。值得注意的是,考虑到 C# 代码可以在任何平台上 运行,通常 运行 两种 Regasm 版本都可以。