Com CLSID自动生成的默认规则是什么?

Com CLSID自动生成的默认规则是什么?,com,registry,guid,clsid,Com,Registry,Guid,Clsid,我们有一个COM组件项目和一个注册COM组件的Windows安装项目。我已经检查了安装项目的上一个版本,似乎为COM项目中的类生成的CLSID总是变化的,即使有时这些类中没有变化。这是我们想要的方式,因为我们希望在同一台机器上保持不同版本的实现。但是,当我手动构建此项目并在同一天多次使用/regfile选项运行regasm.exe时,生成的reg文件中的CLSID始终相同。它认为在以前的情况下,它们发生了变化,这是因为它们是在不同的日子建造的,但我不确定。那么,有人能告诉我这个CLSID自动生成

我们有一个COM组件项目和一个注册COM组件的Windows安装项目。我已经检查了安装项目的上一个版本,似乎为COM项目中的类生成的CLSID总是变化的,即使有时这些类中没有变化。这是我们想要的方式,因为我们希望在同一台机器上保持不同版本的实现。但是,当我手动构建此项目并在同一天多次使用/regfile选项运行regasm.exe时,生成的reg文件中的CLSID始终相同。它认为在以前的情况下,它们发生了变化,这是因为它们是在不同的日子建造的,但我不确定。那么,有人能告诉我这个CLSID自动生成的(默认)规则是什么吗?我想我们在项目中使用的是默认设置

我不确定程序集版本是否会影响结果。但我们将程序集版本号指定为Major.Minor.*,这意味着第三个数字(版本号)是自2000年1月1日起的天数,第四个数字(修订号)是自午夜起的秒数除以2。在CLSID发生变化的情况下,即使类代码没有变化,主数字和次数字也是相同的。因此,如果版本号确实影响CLSID,我可以看出它不仅考虑了主版本号和次版本号

当然,我们没有为这些类分配静态guid,否则它在我们的安装项目中不会改变


谢谢你的帮助

是的,如果不显式使用[Guid]属性,CLR会自动为接口和类生成Guid。它做得很好,它包括程序集和类声明的所有部分,这些部分可能会使您的代码二进制与以前的版本不兼容。在COM中非常重要,这样的不兼容性很难诊断

该算法使用完全指定的类型名以及类型中方法和字段的声明。将它们转换为字符串(“字符串化声明”),并通过散列将结果字符串转换为guid。“完全指定的类型名”是您的死敌,其中包括[AssemblyVersion]。这完全是有道理的,增加程序集版本是一件大事,它会使程序集与使用该程序集的任何代码不兼容。这样的代码必须重新编译。COM客户端也不例外


如上所述,您可以指定自己的[Guid]属性以强制CLSID为特定值。当您出错并进行破坏性更改但不重新编译客户端代码时,可能会调用DLL地狱。失败模式是令人讨厌的,相当随机的访问冲突异常,或者只是简单地调用错误的方法。在执行此操作时,您应该返回ComInterfaceType.IsIDispatch,以便强制客户端代码使用后期绑定。或者用铁拳控制构建和部署过程。

谢谢Hans,这非常有帮助。我们确实希望在不同的构建中保持CLSID的不同。目前它们不会改变的原因是,程序集版本号的生成似乎有一些问题。正如我提到的,第三个和第四个数字应该根据构建日期和时间而改变,但由于某些原因,它们保持不变,这导致CLSID也保持不变。您应该只更改[AssemblyFileVersion]对于没有中断更改的生成。您的意思是不希望根据生成时间自动更改生成和修订号(即使实际代码可能没有任何更改)?那样做有什么害处?我想这是一个懒惰的环境。在我们的部署场景中,我们将COM dll和其他组件安装到安装文件夹中。因此,如果两个版本安装在同一台机器上的不同文件夹中,注册表应该有两个CLSID,每个CLSID最终引用其自己文件夹中的COM dll。并且只有此文件夹中的可执行文件才会使用COM。您认为这种情况有问题吗?[AssemblyVersion]是上帝号,应该只反映代码的版本,而不是它所在的文件的版本。重建项目不会影响COM客户端是否仍然可以使用程序集而无需重新编译。更改内部版本号和修订号可以,但如果程序集的公共接口没有更改,请确保仅将其应用于[AssemblyFileVersion]。该版本不会影响guid。