当使用ComVisible(false)时,指定一个Guid是否有意义?

43
当你在Visual Studio中创建一个新的C#项目时,生成的AssemblyInfo.cs文件包括一个指定程序集GUID的属性。该属性上面的注释指出,如果“此项目暴露给COM”,则会使用它。
我的程序集中没有需要对COM可见的类型,因此我使用了[assembly: ComVisible(false)]进行标记。那么指定GUID有什么意义吗?
我的感觉是“没有”,那么为什么默认的AssemblyInfo.cs文件包含[assembly: ComVisible(false)]和[assembly: Guid("...")]两个元素?
编辑:
总之,回答说明只有在使用COM互操作时才需要指定GUID。因此,在我的情况下,GUID不是必需的。
sharptooth进一步解释说,[assembly: ComVisible(false)]并不意味着不使用COM互操作,因为可以为单个类型覆盖ComVisible。正是因为这个原因,缺省的AssembyInfo.cs包含了[assembly: ComVisible(false)]和GUID两个元素。

相关:https://dev59.com/FnbZa4cB1Zd3GeqPIrKh - StayOnTarget
3个回答

20

当你从一个空的程序集开始并希望向COM公开一些内容时,同时使用[assembly: ComVisible(false)][assembly: Guid("...")]是完全有意义的在某些情况下。因此,你将把程序集标记为不ComVisible,然后再将要公开的实体标记为ComVisible。这就是为什么GUID默认存在的原因。

无论如何,如果你真的不想将任何内容公开给COM,请在项目设置中取消选择“注册COM互操作”选项。


9

在COM中,一致的GUID是绝对必要的。[assembly:Guid]属性生成类型库LIBID。项目模板会自动生成一个,以确保程序员在将ComVisible设置为true时不会忘记提供一个。

如果没有提供程序集[Guid],则Tlbexp.exe会从程序集名称、版本和公钥合成一个。这并不足够好,因为类型库已经有一个版本。更改[AssemblyVersion]将生成不同的LIBID。特别是当您使用版本的自动增量选项(如1.0.*)时,可能会迅速填充注册表,导致大量无效的TypeLib注册表键。

长话短说,这可以避免许多不愉快的意外。


1
不要忘记,您可以在程序集级别上将 ComVisible 设置为“false”,并将其设置为程序集中的类/接口/方法为“true”,后者将覆盖前者。请参阅 https://dev59.com/Z0rSa4cB1Zd3GeqPTA7f 了解如何使用它。因此,在程序集级别上实际上不需要将其翻转为“on”。 - sharptooth
1
只有当您的类型库需要暴露给期望特定接口的COM客户端时,拥有一致的GUID才真正重要。您仍然可以通过IDispatch将对象暴露给COM,而无需永久GUID。 - Josh
哦,迟绑定需要一个一致的ProgID。同样的问题。 - Hans Passant

4

没有必要包含它,除非在非常特定的COM互操作方案中才会需要。尽管我认为使用反射访问GUID可能有一些用处,但并不保证GUID存在,因此您不能依赖它。


它对于需要SSL证书的独立Web服务器有相当大的用途。 - jpaugh
@jpaugh:不确定我们在谈论同一件事情。 - Josh
我自己也不是很确定,但是我不得不使用程序集信息中的GUID才能让该场景正常工作(请参见我的答案底部)。我的(暂时的)结论是Windows使用COM接口将SSL绑定“固定”到特定的应用程序。 - jpaugh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接