【问题标题】:Visual Studio Builds Projects Every Time I Run每次我运行时,Visual Studio 都会构建项目
【发布时间】:2014-06-05 14:42:09
【问题描述】:

我在 Visual Studio 2010 中有一个带有大量项目的 .NET 解决方案。直到最近,当我从 IDE 中运行启动项目时,只有在启动项目或依赖项目之一中的代码发生更改时才会构建项目。

大约两周前,我注意到每次运行启动项目时,Visual Studio 都会构建所有项目,这大约需要 7 分钟。不用说,这会占用我大量的时间,我已经尽力在网上寻找解决方案,但还没有找到任何解决我的具体问题的解决方案。

一些额外的信息 - 在我开始遇到此问题的同时,我团队中的其他人也开始遇到同样的问题。

我们还使用了源代码存储库。由于我们没有更改 Visual Studio 中的任何设置,因此我怀疑有人无意中更改了某些项目的源代码中的某些内容,现在每次都需要构建所有项目。

任何建议将不胜感激。

【问题讨论】:

  • 只是好奇你如何“运行”你的代码?
  • 您的项目是否设置为“注册 COM 互操作”?这就是我的问题。
  • 您的项目是如何被引用的?您是否有任何构建前或构建后操作或自定义构建目标?您的项目是否有很强的命名?
  • 构建输出是否提供任何线索,说明您的项目的最早依赖项始终是过时的?您是否查看过提交历史以了解对项目文件的修改?
  • 你已经知道应该看什么了。在发布 msbuild 跟踪之前,您无法获得可靠的答案。

标签: c# .net visual-studio-2010 visual-studio


【解决方案1】:

原因可能很多,所以没有你的解决方案+项目,我们只能猜测。

我处理这个问题的典型方法是使用二分搜索缩小范围。也就是说,

  1. 我构建一切。
  2. 接下来,我在构建顺序的中间找到了一些东西并构建了该项目。如果该项目所依赖的某些东西是罪魁祸首,那么您将遇到问题。如果它不依赖的东西有你不会的问题(即它会说所有项目都已跳过)。
  3. 现在您重复此过程,直到将范围缩小到(希望) 已开始导致问题的项目。

这(当然)只有在有一个项目引入了新问题(很可能)时才有效。

在我的具体情况下,罪魁祸首之一是有一个 x64 项目引用了一个未选择在 x64 配置中构建的 x86 项目。

【讨论】:

  • 我将按照这些步骤进行操作,并会尽快回复您并告知结果。谢谢。
  • 仅供参考-这些步骤使我隔离了根本原因。我团队中的某个人通过在解决方案中引用项目的二进制版本无意中创建了循环引用,因此二进制版本总是与新编译的版本稍有过时。删除引用解决了这个问题,因为引用甚至不需要开始。感谢您的帮助!
【解决方案2】:

我将分享我在 stackoverflow 上找到的最佳答案,并结合 matt smith 在此处接受的答案,我已经找到了问题的根本原因:

通过将 Visual Studio 配置为以“诊断”方式记录构建输出,如此答案中所述:https://stackoverflow.com/a/29649259/2740778,输出的第一行解释了 MSBuild 决定重新构建项目的原因。

所以,如果你有,让我们把 3 个项目组合成一个解决方案:

  • 图书馆0
  • 图书馆1
  • 应用

以这种方式引用:应用程序引用 Library1,而这个引用 Library0。通过为应用程序项目选择“构建”,第一次它应该按顺序构建所有引用的项目。但是从现在开始,如果没有进行任何更改,则按“构建”不应构建任何内容,因为 MSBuild 会检测到未进行的更改。应该会显示类似的日志输出:

========== 构建:0 成功,0 失败,3 最新,0 跳过 ==========

但是现在,如果进行了更改,如果您将 MSBuild 日志输出级别设置为“诊断”,则输出窗口中的第一行将显示 Visual Studio 决定构建的原因一个项目,比如这里:

项目“Library0”不是最新的。输入文件 'c:\Library0\Class1.cs' 在输出文件 'c:\Library0\bin\Debug\Library0.pdb' 后被修改。

【讨论】:

    【解决方案3】:

    转到工具 -> 选项 -> 项目和解决方案 -> 构建和运行。 看看那里的选项。 'Only build startup projects and dependencies on Run' 应该被选中。

    此外,您可以将构建输出(在同一选项屏幕中)设置为“详细”或“诊断”,以查看是否可以找到每次构建项目的任何线索。

    【讨论】:

    • 感谢您的回复。我们过去曾尝试过您的第一个建议,因为这似乎是一个常见的在线解决方案,但这并没有帮助,而且,在我看来,如果我们都不需要修改 Visual Studio 中的构建设置从一开始就没有改变它们。那有意义吗?关于你的第二个建议,我会尝试一下。我之前已将其更改为诊断,但在构建输出中没有看到任何有用的信息,但我会尝试将其更改为详细。
    • 很遗憾,您的建议没有解决我的问题。
    【解决方案4】:

    根据我对这个问题的经验,只是重建了一些项目,重建失败了好几次才最终成功。这显然是由\rootprojectdir\.vs\%projectname%\v14\.suo 文件损坏引起的。这也导致相同的项目需要重建,并且每次打开 VS 时都会打开相同的窗口。删除 .suo 文件(当 VS 关闭时)并重新打开 VS 修复它:)

    【讨论】:

      【解决方案5】:

      工具 -> 选项 -> 项目和解决方案 -> 构建和运行

      将输出详细程度设置为“诊断”。进行另一次构建后,检查输出窗口。在每个项目构建开始时,构建系统会告诉您是哪个依赖项导致项目被构建。

      (在我的例子中,它是一个 .ico 文件,意外设置为 Build Action: ResourceCopy To Output: Copy if newer。很难找到。)

      【讨论】:

      • 你知道这是否有任何不利因素,“诊断”设置总是打开。这会导致构建速度变慢吗?
      • 它可能有点慢,但差异是如此之小,以至于从未被注意到。就像一个有大约 50 个项目的解决方案一样,可能需要一两秒钟。
      • 创建一个 VS 插件会很有趣,这会更简单。男孩,我真的很想念 CodeWarrior。
      【解决方案6】:

      我来到这里寻找解决我自己情况的方法,但没有一个答案能解决问题。

      经过调查,我发现如果xaml 文件上的Copy to Output Directory 属性值设置为Copy alwaysCopy if newer,则每次都会编译UWP 项目。在过去,这将有助于解决某些编译问题,但是由于在这些文件中引入 xbf 这些值会强制 Visual Studio 每次都重新编译,即使对任何源代码都没有更改。

      我写了一篇关于它的博文:Preventing Visual Studio Recompiles in UWP

      我希望这对某人有所帮助。

      【讨论】:

        【解决方案7】:

        .csproj 中的 TargetFramework 与 app.config 中的 supportedRuntime-sku

        刚刚找到了重建的另一个原因(至少对于新的 sdk 样式项目文件,没有尝试“旧样式”项目):如果 .csproj 文件中的 TargetFramework 元素与 sku 不匹配-app.config 中supportedRuntime-entry 的属性,Visual Studio 也会每次都重新构建项目。

        例如,在 .csproj 中定位 4.6.2

        <Project Sdk="Microsoft.NET.Sdk">
          <PropertyGroup>
            <TargetFramework>net462</TargetFramework>
          </PropertyGroup>
        </Project>
        

        对比4.6.1在app.config中指定

        <configuration>
            <startup> 
                <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
            </startup>
        </configuration>
        

        将触发重建。

        【讨论】:

          【解决方案8】:

          对于 SDK 风格的项目,现在还有“项目和解决方案”->“SDK 风格的项目”->“日志级别”。调试增量构建时,将其设置为“详细”。

          在我的情况下,由于 AutoGenerateBindingRedirects,预计会出现 .dll.config,但没有找到。这导致增量构建失败。最后是Visual Studio的一个bug,通过删除一些项目相关的缓存文件解决了。

          【讨论】:

            【解决方案9】:

            如果 Visual Studio 每次都需要完整构建,我首先会检查我的设置(已经提到过),然后我会检查 VS 使用的条件来确定需要构建的内容。我知道 VS 在检查需要构建的内容时会检查所有输入文件的时间戳。我见过链接生成的文件会导致所有下游依赖项每次都构建的情况,即使生成的文件的内容是相同的。这是 MSDN 增量构建的链接。

            http://msdn.microsoft.com/en-us/library/ms171483.aspx

            我不确定 VS 是否还有其他条件来识别需要构建的项目。

            【讨论】:

              【解决方案10】:

              MSBuild 检测到需要重新构建项目的原因可能有很多。

              就我而言,我有一堆从 XSD 文件生成代码的预构建事件。这些导致项目每次都被重建。然后其他依赖于这个的项目也将被重建。

              【讨论】:

                【解决方案11】:

                在我的情况下,原因是我从 Linux 重新启动到 Windows 后没有同步系统时间。

                【讨论】:

                  【解决方案12】:

                  我遇到了一种特殊情况,我的一些源文件来自未来。我需要通过更改系统时间来测试一些代码,并在将来修改代码。然后,当我切换回呈现这些文件时,会导致项目在每次运行时都重新构建。解决方法很简单,新建一个文件,把修改过的文件的内容复制到那里。

                  【讨论】:

                    【解决方案13】:

                    我在一个低级项目(即许多其他项目所依赖的)中的配置标签有 3 个条目:

                     <Configurations>Debug;Release;Debug31</Configurations> 
                    

                    我一直在试验一种新配置 (Debug31),但忘记了。从项目文件中删除 Debug31 配置解决了该问题。请注意,包含我所有项目的解决方案没有 Debug31 配置。这似乎导致这个项目总是过时,即使我只是在构建“调试”或“发布”。为什么我不确定。

                    【讨论】:

                      【解决方案14】:

                      如果你不想每次都搜索丢失的文件,那么简单的脚本呢?

                      将其放入 vcxproj(.filters) 文件夹并使用奇怪的项目名称作为参数运行
                      cscript printMissingVSprojFiles.js 奇怪的.vcxproj

                      您将获得所有丢失的包含文件的列表(在 ItemGroup / ClInclude 和 ClCompile 中)。

                      var fso = new ActiveXObject("Scripting.FileSystemObject");  
                      var arg = WScript.arguments(0);
                      var xml = readFile(arg), xml2;
                      xml = xml.documentElement.firstChild;
                      do {
                          while (xml && xml.nodeName != "ItemGroup") xml = xml.nextSibling;
                          if (!xml) break;
                          xml2 = xml.firstChild;
                          while (xml2 && (xml2.nodeName == "ClInclude" || xml2.nodeName == "ClCompile"))
                          {
                              var path = xml2.attributes.getNamedItem("Include").nodeValue;
                              if (!fso.FileExists(path))
                                  WScript.Echo(path);
                              xml2 = xml2.nextSibling;
                          }
                          xml = xml.nextSibling;
                      } while (xml);
                      
                      function readFile(filename)
                      {
                          var xml = new ActiveXObject("Msxml2.DOMDocument.6.0");  
                          xml.async = false;
                          xml.load(filename);
                          return xml;
                      }
                      
                      function writeFile(filename, content)
                      {
                          var TextStream = fso.CreateTextFile(filename);
                          TextStream.Write(content);
                          TextStream.Close()
                      }
                      

                      【讨论】:

                        【解决方案15】:

                        以下内容对我有用。 转到 Properties->Custom_Build_Step,并删除“Description”字段中的任何内容。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2017-02-06
                          • 1970-01-01
                          • 2013-02-16
                          • 2015-11-29
                          • 2013-11-22
                          相关资源
                          最近更新 更多