我们有一个COM组件项目和一个注册COM组件的Windows安装项目。我已经检查了安装项目的上一个版本,似乎为COM项目中的类生成的CLSID总是会更改,即使有时这些类中没有更改。这是我们想要的方式,因为我们希望在同一台机器上保留不同的版本。但是,当我手动构建此项目并在同一天多次使用/ regfile选项运行regasm.exe时,生成的reg文件中的CLSID始终相同。它认为在之前的情况下,它们发生了变化,这是因为它们是在不同的日子建造的,但我不确定。那么有谁能告诉我这个CLSID自动生成的(默认)规则是什么?我想我们正在使用项目中的默认设置。
我不确定程序集版本是否会影响结果。但我们将程序集版本号分配为Major.Minor。*,这意味着第三个数字(内部版本号)是自1.1.2000以来的天数,第四个数字(修订版号)是自午夜以来的秒数除以2。在CLSID改变的情况下,即使类代码没有改变,主要和次要数字也是相同的。因此,如果版本号确实影响了CLSID,我可以告诉它不仅要考虑主要和次要数字。
当然,我们没有为这些类分配静态GUID,否则它们在我们的安装项目中不会改变。
感谢您的帮助!
答案 0 :(得分:2)
是的,如果您没有明确使用[Guid]属性,CLR会自动为接口和类生成guid。它做得很好,它包括程序集和类声明的所有部分,可能会使您的代码二进制文件与以前的版本不兼容。在COM中非常重要,这种不兼容性可能非常难以诊断。
该算法使用完全指定的类型名称以及类型中的方法和字段的声明。将它们转换为字符串(“将声明字符串化”)并通过散列将结果字符串转换为guid。 “完全指定的类型名称”是你的克星,包括[AssemblyVersion]。这完全有道理,增加程序集版本是一项大交易,使程序集与使用程序集的任何代码不兼容。这样的代码必须重新编译。 COM客户也不例外。
如上所述,您可以指定自己的[Guid]属性以强制CLSID为特定值。当你弄错了并且做出重大修改但是不重新编译客户端代码时,有可能调用DLL Hell。失败模式是令人讨厌的,相当随机的AccessViolation异常或只是简单地调用错误的方法。当你这样做时,你应该回到ComInterfaceType.IsIDispatch,这样客户端代码就会被迫使用后期绑定。或者用铁拳控制你的构建和部署过程。