【发布时间】:2011-06-16 02:27:43
【问题描述】:
在我从事的项目中,我们遇到了一个奇怪的错误。这是由于我们做了一些奇怪的分支而对版本号进行了一些有趣的操作造成的。我们已经解决了这个问题,但我很好奇我是否能得到关于 msbuild 所表现出的行为的解释。使用 Nant 和 Visual Studio 2008 构建时观察到相同的行为。
设置:程序集的版本号由链接到所有程序集属性的公共文件控制。这样做是为了使它们彼此同步。但是,我们有一些程序集是预编译的,只是偶尔构建。它们用于序列化,部分由 XSD 生成。由于序列化不会经常改变,它们显然不需要经常重建。
情况:链接文件中的版本号已更新。发生这种情况后,由于序列化发生了变化,重新构建了预编译的程序集。发生这种情况后,决定需要较低的版本号。公共链接文件再次更新,但版本号比以前低。
问题:在最后一次更新版本号后,构建停止将一些 dll 复制到一个特定项目的输出目录,停止正常工作。我们将此项目称为 A。A 依赖于程序集 B,程序集 B 依赖于程序集 C,而程序集 C 依赖于预编译的 dll 之一。这似乎是一条长链,但这条链是关键。另一个关键事实是 A 没有直接引用 C。当 A 在降低版本号之前构建时,C 被复制到输出目录中。这个问题是,版本号降低后C不再被复制到输出目录中。有三种方法可以纠正这个问题。如果进行了任何这些更改,则 C 将正确复制到输出目录。
- 在 A 的项目中添加对 C 的直接引用。
- 版本号被改回或高于构建预编译 dll 时的版本号。
- 使用版本号更新重建预构建的程序集。
第三个选项是如何解决问题。我的问题是这是 msbuild 的错误还是预期的行为?这种行为的目的是什么?为什么不将 dll 复制到输出目录而不是创建错误?
【问题讨论】:
-
在A中添加对C的直接引用时,是“特定版本=true”吗?另外检查您在 GAC 中没有版本,如果.net 已经在 GAC 中找到该文件,则默认情况下不会复制该文件(即使您在 Visual Studio 中构建它也是如此)。你说的预制组件是什么?它们是由另一个解决方案构建并由绝对文件路径程序集引用引用的吗?
-
它不在 GAC 中,我必须检查具体的版本问题,但我认为不是。它们是使用 SGEN 创建的序列化 DLL。它们是在另一个解决方案中构建的,并由相对路径引用。
-
我想我复制了你的设置,但结果不同。项目 A、B 和 C 是同一解决方案的一部分。按预期增加版本副本,但是降低 C 的版本仍然会导致在 VS2010 中构建时 C 覆盖更高版本。这是因为解决方案知道 B 具有对 C 的显式程序集引用,并且找不到“特定版本”。我只能假设“文件版本”与外部文件不同,当在同一解决方案的一部分中对其他项目进行程序集引用时,它没有影响。我的外部 SGEN 程序集无论如何都会被复制。