Visual Studio 重新构建未修改的项目

86
所以,正如标题所述,我现在有一个包含大约50个项目的VS2010解决方案。如果我对一个“顶层”项目进行更改,而没有任何引用它的内容,那么VS仍然会重新构建所有50个项目。我正在运行没有任何附加组件的Visual Studio 2010 Ultimate。我正在使用ILMerge将所有项目合并为单个文件。
通过检查较低级别的dll时间戳,我已经验证了这一点,并且发现它们确实被重建,即使它们的代码没有被修改。
我已阅读以下所有回复和评论: Visual Studio 2008 keeps rebuilding Visual studio keeps building everything Strange VS2010 build glitch occurs in my solution

在Visual Studio中重新构建C#项目的原因

但是,大多数建议卸载项目以加快构建时间,但没有具体的修复方案。我正在尝试弄清楚为什么VS认为这些依赖项项目需要重新构建,而它们实际上不需要,并进行修复。

我已经打开了“工具>选项>项目和解决方案>生成和运行>仅在运行时构建启动项目和依赖项”,但没有效果。

此外,如果我只重新构建一个“中级”项目,该项目仅有8个(间接)依赖项,则它仍会构建所有8个项目,即使没有调用ILMerge并且没有修改任何依赖项项目。

感谢大家提供的任何见解。

添加

为了测试一些建议,我从头开始创建了一个新的WinForms项目。然后我在该解决方案中创建了两个新项目。我将我两个“最底层”项目的所有代码和资源(不包括项目文件)复制到了这两个全新的项目中(我通过将文件和文件夹从资源管理器中拖放到Visual Studio中的项目中来完成此操作)。

最低的项目,我们称之为B,没有引用任何其他项目。下一个项目A只引用了B。因此,一旦我将所需的.NET和外部程序集引用添加到项目中,解决方案就能够构建。
然后,我让我的新WinForm项目引用A并进行了完整的构建。因此,引用链是: WinForm -> A -> B 然后,我仅修改了WinForm并进行了标准构建(F6)。与以前一样,Visual Studio重新构建了所有三个项目。
经过对项目B源文件的系统性排除,我发现如果我删除了Resources.Designer.csResources.resx(并注释掉使用这些资源的.Properties.Resources对象的代码),那么修改WinForm将不再重建整个解决方案,而只会重建WinForm
Resources.resxResources.Designer.cs添加回项目B(但将引用的代码注释掉,以便没有任何内容使用资源),可以重新引入完整的构建行为。
为了确定我的资源文件是否已损坏,我再次删除它们,然后创建一个新文件(通过项目属性->资源),并重新添加与之前相同的资源,这是一个单独的Excel文件。在此设置下,仍将发生完全重建。
然后我删除了单个资源,但保留了项目B中的资源文件。即使没有添加资源,但仍在项目中保留资源文件,也会发生完全(不必要的)重建。
似乎只要向.NET 3.5项目添加了资源文件,Visual Studio 2010就会始终重建该项目。这是一个错误还是预期的行为?
再次感谢大家!

1
你可以尝试直接使用MSBuild构建它,看看是否仍然会出现这种情况。 - Daniel Powell
1
我的理解是VS调用msbuild(而项目基本上是一个msbuild脚本https://dev59.com/_XI_5IYBdhLWcg3wK_s6),所以我不确定这会改变什么。我怀疑我只会重新创建相同的构建脚本,然后从命令行运行它。直接运行msbuild有什么不同的方法吗?或者有没有办法找出为什么msbuild认为需要重新构建项目? - Matt Klein
2
普通构建(F6)和有时仅项目构建(Shift-F6)。两者表现相同,尽管“仅项目构建”的重建项目范围仅限于当前项目的直接和间接依赖项。 - Matt Klein
@MattKlein 如果你有一个简单的演示项目展示了这个问题,你应该向微软报告 - http://connect.microsoft.com/VisualStudio - Qwertie
我在一个引用了多个手动构建的.csproj文件的解决方案中遇到了这个问题。每个项目都自动包含源代码:<Compile Include="**\*.cs" Exclude="obj\**\*.cs" />。当我删除(不必要的)Exclude属性时,我的依赖检查问题消失了。奇怪的是,我有18个使用这种模式的项目,但只需要更改其中两个就可以让事情正常工作。我怀疑问题在于Visual Studio无法处理所有可能的有效MSBuild语法。 - yoyo
显示剩余4条评论
18个回答

1
我终于找到了另一个罪犯,这让我在增加构建日志详细程度时很难找到。
在某些情况下,MSBuild会在输出文件夹中查找vc120.pdb文件,如果该文件不存在,它将重建整个项目。即使您已禁用调试符号生成,也会发生这种情况。
解决方法是启用调试符号并生成此文件,然后再次禁用设置,而不删除PDB文件。

这个选项在使用源代码控制的团队中会如何扩展?你会将PDB文件检入源代码中吗(听起来很糟糕)?否则,每当有人获得此项目的最新版本时,都需要执行此手动步骤。 - julealgon
@julealgon:毫无头绪 :/ - user541686

0

对于这类构建问题,将MSBuild输出详细程度设置为“诊断”确实是必要的第一步。大多数情况下,重新构建的原因足以采取行动,但偶尔MSBuild会错误地声称某些文件已被修改并需要复制。

如果是这种情况,您需要禁用NTFS隧道或将输出文件夹复制到新位置。在此处有更详细的说明。


0

我和你遇到了同样的问题。 我发现这是由于一些已删除的文件引起的。 当我从项目中移除这些文件后,问题就解决了。 祝好。


0

这里是来自VS2010总是重新构建解决方案?的答案:

通过更改项目文件、清理解决方案、手动删除所有bin文件夹、重启Visual Studio并重新构建所有内容,可以解决此问题。


我不确定“更改项目文件”是什么意思,但我已经尝试了其中的其余部分,没有任何效果。看起来可能与资源文件有关(请参见问题中添加的信息)。 - Matt Klein

0
在我的情况下(混合了C#,C++/CLI和本机C++解决方案),即使没有任何更改,一些C++项目也会被重新链接。我花费了很长时间来尝试弄清楚发生了什么。最后,我从“命令行”选项中找出了PDB输出路径(选项/Fd)无法处理文件夹设置$(IntDir)。我删除了它 - 空值将正确执行默认操作 - 我的问题就解决了。

0

我遇到了一个问题,当我从Visual Studio 2015升级到2017时,它会重新构建项目。我添加了这个答案,让那些可能遇到类似问题的人受益,因为好像没有地方记录这个问题。

在我的情况下,问题是解决方案中所有项目都有相同的中间输出路径(obj)。文件GeneratedInternalTypeHelper.cs由所有包含XAML的项目生成。在Visual Studio 2015之前,构建过程显然没有检查此文件的文件日期,因此没有发生任何问题。但是使用VS2017后,此文件的文件日期将被检查,并且因为构建过程中稍后的项目将覆盖它(具有相同的内容),所以较早的项目将重新构建,反复触发后面的实际上就无限循环了。

在这种情况下的解决方案是确保所有项目具有不同的中间输出目录,这将使问题消失。


0

不存在的文件是一个问题,显然没有输出的文件也是如此。这可能发生在静态库中有一个资源文件的情况下。(C++)


0

正如其他人所注意到的那样,一个可能的原因是将CopyToOutputDirectory设置为Always。可以通过应用以下PowerShell脚本来同时修复所有项目文件:

$folder = "C:\My\Solution\Folder"
$csvFiles = Get-ChildItem $folder *.csproj -rec
foreach ($file in $csvFiles)
{
    (Get-Content $file.PSPath -Encoding UTF8 -Raw) |
    Foreach-Object { $_ -replace "<CopyToOutputDirectory>Always</CopyToOutputDirectory>", "<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>" } |
    Set-Content $file.PSPath -Encoding UTF8 -NoNewline
}

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