Visual Studio重建未修改的项目

时间:2013-02-17 00:25:59

标签: c# visual-studio-2010 visual-studio msbuild ilmerge

所以,正如标题所示,我现在有一个VS2010解决方案,里面有大约50个项目。如果我对没有引用的“顶级”项目进行更改,那么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

Reasons for C# projects to rebuild in Visual Studio

但是他们中的大多数只是提供卸载项目的建议,以加快构建时间,但没有具体的解决方案。我试图弄清楚为什么VS认为这些依赖项目需要重建时才能修复它。

我已启用'工具>选项>项目和解决方案>构建并运行>仅在运行时构建启动项目和依赖项,但不起作用。

另外,如果我只是重建一个只有8个(in)直接依赖项的“中级”项目,那么即使没有调用ILMerge并且没有修改任何依赖项目,它仍会构建所有8个项目。 / p>

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

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

最低的项目,我们称之为 B ,没有引用任何其他项目。下一个项目 A 仅引用 B 。因此,一旦我将所需的.NET和外部程序集引用添加到项目中,那么解决方案就会构建。

然后我获得了我的新WinForm项目参考 A 并完成了完整版本。所以ref链是:

WinForm - > A - >的

然后我修改了 WinForm 并进行了标准构建(F6)。和以前一样,Visual Studio重建了所有三个项目。

在项目 B 中对源文件进行了一些系统的删除后,我发现如果我删除了Resources.Designer.csResources.resx(并注释掉了使用{的代码{1}}这些资源的对象)然后修改 WinForm 将不再重建整个解决方案,只会重建 WinForm

.Properties.ResourcesResources.resx添加回项目 B (但将引用的代码注释掉,以便没有任何资源使用这些资源)会重新引入完整的行为。

要查看我的资源文件是否已损坏,我再次删除它们然后创建一个新文件(通过Project Properties - > Resources)并重新添加与以前相同的资源,这是一个单独的Excel文件。使用此设置,仍将进行完全重建。

然后我删除了单个资源,但将资源文件保留在项目 B 中。即使没有添加资源,但资源文件仍在项目中,也会发生完全(不需要的)重建。

似乎只是将资源文件添加到(.NET 3.5)项目中将导致Visual Studio 2010始终重建该项目。这是一个错误或预期/预期的行为吗?

再次感谢所有人!

17 个答案:

答案 0 :(得分:112)

打开工具 - 选项,选择项目和解决方案 - 在树中构建和运行,然后将“MSBuild项目构建输出详细程度”设置为Diagnostic。 这将输出建立项目的原因,即

  

项目'ReferencedProject'不是最新的。项目项目   'c:\ some.xml'将'复制到输出目录'属性设置为'复制   总是。

  

项目'MyProject'不是最新的。输入文件   输出文件后修改'c:\ ReferencedProject.dll'   'C:\ MyProject.pdb'。

在这种情况下,修复是仅在较新时复制some.xml。

构建前事件和后期构建事件也可以触发构建。

答案 1 :(得分:17)

虽然我不认为这是一个解决方案,但这是一种适用于我的情况的解决方法......

我原本在50个中包含Resources部分的大约5个项目。这些项目将永远重建,因此他们所依赖的任何东西也将被重建。这5个项目中的一个是一个“基础”级别的库,其他项目中有48个被引用,因此,即使不需要,也会每次重建96%的项目。

我的解决方法是使用依赖注入,接口和专用的“资源”项目。我没有让这5个项目引用他们自己的Resources对象,而是在每个项目中创建了一个提供所需资源的接口。然后,需要这些资源的类将要求在构造函数(构造函数注入)中创建它们时传入接口。

然后我创建了一个单独的“Resources”项目,它有一个像normal一样的实际Resources部分。该项目仅包含资源本身,以及通过接口提供这些资源所需的每个接口的类。该项目将引用具有资源依赖性的所有其他项目,并实现项目所需的接口。

最后,在我的“顶级”项目中没有引用任何内容(以及exe实际构建的地方和我的作品根目录)我参考了“资源”项目,连接了DI,然后我们去了。

这意味着每次只会重建两个项目(“资源”和“顶级”),如果我进行部分构建(Shift-F6),那么它们根本不会被重建。 / p>

同样,这不是一个很好的工作,但是每次构建需要大约3分钟时就会构建48个项目,所以我每天都会因为不必要的重建而损失30到90分钟。重构需要一段时间,但我认为这是一项很好的投资。

这是一个简化的图表。请注意,为了减少混乱,不会显示从Main.exeProj1Proj2的依赖关系。

Diagram of solution

通过这种设计,我可以在不触发完全重建的情况下进行Proj1Proj2的构建,因为它们对Resources部分没有任何依赖性。只有Main知道Resources实施。

答案 2 :(得分:16)

当项目的文件确实存在时会发生这种情况 项目无法确定文件是否已更改(因为它不存在),因此它会重建。

只需查看项目中的所有文件,然后搜索附近没有可展开箭头的文件。

答案 3 :(得分:9)

我在VS 2015中遇到了同样的问题。

我的诀窍是:

  1. 一个项目在其他项目bin中引用了自己的副本(魔术,是的)。切换到诊断构建输出(在构建选项中),然后尝试从项目层次结构的顶部逐个构建项目时,可以找到这种东西 - 如果您看到即使没有任何更改也会重建项目,那么请查看它引用。
  2. 我已将所有项目中的所有“copy always”文件更改为“copy if new”。基本上,在所有.csproj文件中,将<%= link_to "Visit Website", job.link , class: "detail" %> 替换为<CopyToOutputDirectory>Always</CopyToOutputDirectory>
  3. 然后我按照this文章中的描述使用此PowerShell脚本禁用了NTFS隧道:
  4. <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

    之后我需要进行重建,现在似乎有效。

答案 4 :(得分:4)

在我的情况下,罪魁祸首是将参考dll的“复制本地”设置设置为true,并将“复制到输出目录”设置为始终复制的文件。

答案 5 :(得分:1)

我遇到了同样的问题,事实证明它与几个项目相关,这些项目在其自己的输出目录中具有对dll的本地复制副本。

找到它的关键是为构建输出设置诊断输出,同时还要知道在日志中查找什么。搜索:“ 不是最新的”是关键。

答案 6 :(得分:1)

MSBuild团队正在收集有关调查构建增量问题的文档: https://github.com/Microsoft/MSBuild/wiki/Rebuilding%20when%20nothing%20changed

答案 7 :(得分:1)

我终于找到了另一个罪魁祸首,我很难通过增加构建日志的详细程度来找到它。

在某些情况下,MSBuild会在输出文件夹中查找 vc120.pdb ,如果此文件不存在,它将重建整个项目。即使您已禁用调试符号生成,也会发生

此处的解决方法是启用调试符号并生成此文件,然后再次禁用该设置,而不删除PDB文件。

答案 8 :(得分:0)

对于.Net Core项目,以上所有解决方案均不起作用。 我找到了解决方案。如果您使用的是Visual Studio 2019:

  1. 构建解决方案两次
  2. 打开Tools-> Options-> Projects and Solutions-> SDK-Style Projects-> Logging Level-> Verbose
  3. 清除输出窗口
  4. 建立您的开始项目
  5. 检查输出窗口。以FastUpToDate开头的所有字符串
  6. 您会找到一些项目项目,这些项目使您的项目不是最新的。
  7. 修复这些问题,然后从步骤1重新尝试。如果您的修复正确,您将在构建输出的最后一个字符串中达到Build: 0 succeeded, 0 failed, {n} up-to-date, 0 skipped

答案 9 :(得分:0)

以下是VS2010 always rebuilds solution?

的答案
  

通过更改项目文件,清洁解决方案,   手动删除所有bin文件夹,重新启动Visual Studio和   重建一切。

答案 10 :(得分: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
}

答案 11 :(得分:0)

就我而言(混合的C#,C ++ / CLI和本机C ++解决方案),即使没有任何更改,某些C ++项目也正在重新链接。我花了很长时间试图找出正在发生的事情。最后,我从“命令行”选项得出结论,PDB输出路径(选项/ Fd)无法处理文件夹设置$(IntDir)。我删除了它-一个空值将正确地执行默认设置-我的问题就消失了。

答案 12 :(得分:0)

从Visual Studio 2015升级到2017时,我遇到了Visual Studio重建项目的问题,我添加了这个答案,以便为那些可能遇到类似问题的人带来好处,因为它似乎没有记录在任何地方。

就我而言,问题是解决方案中的所有项目都具有相同的中间输出路径(obj)。 GeneratedInternalTypeHelper.cs文件由包含XAML的所有项目生成。到Visual Studio 2015,构建过程显然没有检查此文件的文件日期,因此没有出现问题。使用VS2017,将检查此文件的文件日期,并且因为构建过程中的后续项目将覆盖它(具有相同的内容),早期的项目将重新构建,重新触发后续构建,无限制。

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

答案 13 :(得分:0)

经常发生的另一个问题是,解决方案中的某个项目具有未来的修改过的标记。如果您将时钟向前设置,然后将时钟设置为正确的时间,则会发生这种情况。我在安装Linux时遇到了这种情况。

在这种情况下,您可以使用git bash递归触摸所有文件(是的,在Windows中):

find . -exec touch {} \;

答案 14 :(得分:0)

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

如果是这种情况,您需要禁用NTFS隧道或将输出文件夹复制到新位置。 Here it is in more words.

答案 15 :(得分:0)

我和你有同样的问题。 我发现它来自一些已删除的文件。 当我从项目中删除文件时,问题就消失了。 问候。

答案 16 :(得分:0)

根据您的观察,听起来您有一些项目以一种不明显的方式表达对其他项目的依赖性。孤立的依赖项可能保留在项目文件中,而不会在UI中显现。在文本编辑器中打开后,您是否查看了行为不端的项目文件?检查解决方案构建依赖关系?

如果您无法发现任何内容,请尝试从头开始重新创建一个项目,以查看新项目是否存在同样的问题。如果干净的项目正确构建,您将知道您在某处表达了不需要的依赖项。据我所知,这些必须在项目文件或解决方案文件中,除非你有makefile或其他不寻常的构建步骤。