所有问题都与.net Framework 2.0中的.net项目dll有关,该dll将自身公开为COM。
1)如果我们在源代码(typelib,类,接口)中未指定任何GUID,那么谁在生成GUID?编译还是高潮?
2)GUID值存在于dll,tlb或两个文件中吗?
3)任何具有相同源代码的开发人员都将在她构建或运行加气的计算机上独立生成非常相同的GUID?
4)如果我通过现有的dll和tlb文件运行regasm,如果dll和tlb不匹配怎么办? Regasm使用最新元素和GUID重新生成tlb文件吗?还是在当前的tlb文件中注册TypeLib?
5)使用dll和tlb参数设置运行regasm有什么意义? Tlb文件是部署内容的一部分,还是最佳做法是仅部署dll并让regasm即时生成tlb?
6)最后一个问题,真的需要tlb吗?拥有tlb文件的意义是什么?并非所有信息都已在注册表中?它提供什么额外的信息?
7)在注销时,我们需要提供什么? dll文件? Tlb?都?如果dll(或tlb)与现有的reg条目不匹配怎么办?如果已经使用tlb选项注册,但我只运行dll的regasm unregister,它也会删除TypeLyb条目吗?
8)关于位,再充气也总是在SysWow64下生成条目吗? Framework64下的重制与Framework下的重制相同吗?
答案 0 :(得分:5)
类型库与.NET元数据完全等效。它对客户端程序员最重要的是,它使编译器和IDE更加了解您的库。提供自动完成和语法检查功能,因此他的代码与您的代码不匹配的几率很小。注册步骤是必需的,以便可以找到您的文件。通常将类型库作为资源嵌入到DLL本身中,例如.NET元数据,但是.NET构建模型并不容易做到。客户端编译器使用类型库信息来生成适当的COM调用。指导很重要,因为这是客户端编译器需要使用的,标识符名称不起作用。有一种方法可以使用使用名称的“后期绑定”,这与.NET中的Reflection完全等效,但不涉及类型库。
谁在生成GUID?
CLR可以。每个.NET接口或类都有一个,无论是否为[ComVisible(true)]。也通过Type.GUID属性公开。如果您没有在类型上使用[Guid]属性,则它将运行一种算法来生成Guid,该Guid将类型声明用作输入。换句话说,如果您对类型进行了任何更改,则可以确保Guid的值将有所不同。这是您永远不要使用[Guid]属性的基本原因,除非您必须创建精确的直接替换并且不能重新编译客户端代码。 TLBID来自创建项目时自动生成的AssemblyInfo.cs文件。
在dll,tlb或两个文件中?
它仅在使用[Guid]属性时存在于DLL中,但是通常如上所述在运行时生成。它始终存在于类型库中,这就是客户端编译器知道如何创建类的对象并使用其接口的方式。
将生成完全相同的GUID
是的,只有类型声明才起作用。
如果我通过现有的dll和tlb文件运行regasm
Regasm只能根据其/ tlb选项的要求创建一个类型库,它不能使用现有的类型库。否则,它将执行与Tlbexp.exe完全相同的操作,使用Reflection枚举程序集中的类型以查找[ComVisible(true)]类型并生成匹配的类型库声明。它要做的额外事情是将类型库的注册表项写入HKLM / Software / Classes / Typelib。这样客户端IDE可以找到它。
使用dll和tlb参数设置运行regasm有什么意义?
没有“ dll参数”的真实含义。如上所述,使用/ tlb生成类型库。是否部署类型库取决于其用法,如果不同时提供客户端代码,则应始终部署它,以便客户端程序员可以使用它。类型库的其他用法是this post的主题。如果您不确定客户端程序员将如何使用您的代码,请始终进行部署。
不是所有的信息都已经在注册表中了吗?
注册表中的内容是有限的,只有足够的信息才能找到类型库文件。类型库中包含接口的描述,它们的方法签名,guid和工厂函数所需的CLSID。
在注销时,我们需要提供什么?
与注册完全相同,只需添加/取消注册。如果以前使用过/ tlb,还必须提供它,以便可以删除TypeLib注册表项。在您忙于开发和测试库时,将其自动化非常重要,因为Guid通常是自动生成的,因此您可能在注册表中产生大量垃圾。当您忘记运行Regasm时,还会感到头疼。项目>属性>构建选项卡,“注册COM互操作”复选框。但不利的一面是,您必须运行提升的VS,这样它才能写入注册表。
重排也会在SysWow64下始终生成条目吗?
SysWow64不起作用,请始终避免部署到c:\ windows。但是,是的,位数确实很重要,注册表的结构合理,因此64位应用程序不能在32位库中意外创建对象并在丑陋的异常中死亡。反之亦然。一个32位客户端应用程序将从HKLM / Software / WOW6432Node读取注册表项,只有使用32位版本的Regasm时,您才能获得注册表项。值得注意的是,考虑到C#代码可以在任何平台上运行,通常可以同时运行两种Regasm。