如何在Visual Studio中实现自动版本号?

17

我们的代码库要求自动编号程序集,我将默认版本号1.0.0.0更改为1.0.*,如下所示:

[assembly: AssemblyVersion("1.0.*")]

这样可以生成所需的编号。

但是,该代码库有数百个DLL文件,其中许多引用彼此。现在,当我编译某些项目时,它们会抱怨需要的已引用组件的DLL版本不正确,并且它们无法构建:(

我应该如何解决呢?我们需要在编译代码库层次结构底部的DLL时,所有引用它的其他DLL都能正确工作,而无需重新编译。

我收到的错误消息类似于这样:

Error   1   CA0058 : The referenced assembly 'Library1, Version=1.0.4146.17993
, Culture=neutral, PublicKeyToken=d9c65edd2096ad48' could not be found. This assembly
is required for analysis and was referenced by:
D:\Work\Source Code\Library\Library2\bin\Release\Library2.dll.

版本号1.0.4146.17993不正确——DLL的值更高。我们设置DLL为本地复制,因为我们提供的软件需要它(不要问为什么)。被本地复制的DLL是具有更高版本号的那个,而这正是我们想要的。

到目前为止,我尝试过更改引用,将“Specific Version”标志设置为false,但这没有帮助。

5个回答

8
当使用1.0.*语法时,VS生成的版本号不一定会按顺序递增。文档中有这样的说明(加粗部分):
您可以指定所有值,也可以使用星号(*)接受默认的构建号、修订号或两者都使用。例如,[assembly:AssemblyVersion("2.3.25.1")]表示2为主版本,3为次版本,25为构建号,1为修订号。版本号如[assembly:AssemblyVersion("1.2.")]指定1为主版本,2为次版本,并接受默认的构建和修订号。版本号如[assembly:AssemblyVersion("1.2.15.*")]指定1为主版本,2为次版本,15为构建号,并接受默认的修订号。默认的构建号每天递增。默认修订号是随机的。
如果您非常重视版本控制的准确性,我强烈建议您使用第三方解决方案。Build Version Increment 插件是非常出色的选择。
您需要做的是手动管理程序集版本。只有在对程序集的公共接口进行了破坏性更改时才应该增加此版本号。即使您没有在代码中更改任何内容,更改此属性也会使您的程序集与引用它的其他程序集不兼容。相反,您希望自动增加的只是程序集文件版本,而不是程序集版本。与程序集版本不同,CLR 不会检查此属性以确定兼容性。
Build Version Increment 插件为您提供了对增量控制的细粒度控制,让您可以正确地完成此操作。这应该是 Visual Studio 的标配。

只要整体版本号增加(Visual Studio系统基于日期和时间),我们不必担心版本是否按顺序排列。即使手动递增或使用其他解决方案,我认为我们仍会遇到同样的问题。 - Richard
1
@Richard:确保你刷新页面以查看我的最新编辑。如果你修改了[AssemblyVersion]属性,那么你将会告诉CLR这个程序集与之前的版本不兼容。相反,你需要增加[AssemblyFileVersion]属性。Visual Studio并不能正确处理这个问题,但第三方工具可以让你更好地控制哪一个属性被增加。 - Cody Gray
最终我回到了固定的汇编版本,并手动更新文件版本。如果您有任何建议,可以在构建时自动执行此操作的工具,我会很感兴趣。 - Richard
1
@Richard:你试过使用Build Version Increment吗?我曾经用它来实现这个功能。 - Cody Gray
2
自从.Net 4.5以后,修订号不再是随机的,而是经过计算的。默认修订号是当地时间午夜后的秒数(不考虑夏令时的时区调整),除以2。 - Roman Gudkov
显示剩余2条评论

3

这实际上是一个相当深入的问题,我希望有人能详细回答你,但是在控制汇编信息后,我的建议是您应该考虑使用Nuget来管理您的依赖项。这样,当A团队发布X程序集的v2版本时,他们只需将其放在您的Nuget仓库(可能是网络共享)中,然后您就可以在消耗DLL的项目内部右键单击 <更新。

我还建议查看http://semver.org/并使用语义化版本控制。如果您不想遵循此类系统(或者为您的商店制定类似的标准),那么甚至尝试对您的DLL进行版本控制都没有价值,因为这只会给您带来巨大的头痛。然而,使用语义化版本控制将使您的版本号实际上有一定含义,而不仅仅是随意添加到当前版本中的标签。


1

0
   > However, the code library has many hundreds of DLLs,

如果您可以接受所有源项目及其生成的dll文件具有相同的版本号,那么您可以将版本号放入一个文件中,该文件在所有dll之间共享,如shared AssemblyInfo.cs所述。因此,如果有新的发布/版本,您(或您使用的版本号生成器)只需更新一个文件。

这并没有回答您最初的问题,但可能是依赖性问题的简单解决方法。


0

删除您在使用它的项目中的引用,然后通过指向项目引用类型重新进行引用。

附注:如果在添加引用时,选择浏览并指向 DLL 始终存在的位置,则引用不会被破坏!


GAC 中没有这个。这些都是保存在库文件夹中的 DLL。 - Richard
@Richard,大多数情况下这是解决构建错误的简单答案,很多时候你会得到一个文件引用,指向另一个项目的bin文件夹中的dll,而不是真正的项目引用。通常只需删除该引用,并通过对话框使用添加项目引用即可解决问题。 - Chris Marisic
我认为问题在于项目没有重新构建。因此,当A项目引用库A和库B时,而库B也引用库A时,库B所了解的库A的真实版本不一定是正确的。因此,删除和替换引用无效。重新构建可能有效,但这需要几个小时的时间。 - Richard

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