C# Visual Studio 重建未修改的项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14916729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Visual Studio Rebuilds unmodified projects
提问by Matt Klein
So, as the title reads, I have a VS2010 solution with ~50 projects in it right now. If I make a change to a "top level" project that nothing references then VS still rebuilds all 50 projects. I'm running Visual Studio 2010 Ultimate without any add-ons. I am using ILMerge to consolidate all of the projects into a single file.
所以,正如标题所说,我现在有一个 VS2010 解决方案,其中包含大约 50 个项目。如果我对没有任何引用的“顶级”项目进行更改,那么 VS 仍会重建所有 50 个项目。我正在运行 Visual Studio 2010 Ultimate,没有任何附加组件。我正在使用 ILMerge 将所有项目合并到一个文件中。
I have verified this by checking the time stamps of the lower level dlls and see that they are indeed rebuilt even though their code wasn't touched.
我已经通过检查较低级别 dll 的时间戳验证了这一点,并看到它们确实被重建,即使它们的代码没有被触及。
I've read all responses and comments for:
我已阅读以下所有回复和评论:
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
But most of them just offer suggestions on unloading projects to speed up build times but nothing concrete as to a fix. I'm trying to figure out why VS thinks these dependent projects need to be rebuilt when they don't and fix it.
但是他们中的大多数只是提供有关卸载项目以加快构建时间的建议,但没有具体的修复方法。我试图弄清楚为什么 VS 认为这些依赖项目不需要并修复它时需要重建。
I've turned on 'Tools > Options > Projects and Solutions > Build and Run > Only build startup projects and dependencies on run' but with no effect.
我打开了“工具>选项>项目和解决方案>构建和运行>仅在运行时构建启动项目和依赖项”但没有效果。
Also, if I just rebuild a "mid-level" project that only has 8 (in)direct dependencies then it still builds all 8 projects even though ILMerge isn't invoked and none of the dependent projects have been modified.
此外,如果我只是重建一个只有 8 个(in)直接依赖项的“中级”项目,那么即使没有调用 ILMerge 并且没有任何依赖项目被修改,它仍然会构建所有 8 个项目。
Thank you everyone for any insight you may be able to provide.
感谢大家提供的任何见解。
Added
添加
To test some of the suggestions I created a new WinForms project from scratch. I then created two new projects inside that solution. I copied all of the code and resources (not project file) from my two 'lowest level' projects into the two brand new projects (I did this by dropping the files and folders from Explorer onto the project in Visual Studio).
为了测试一些建议,我从头开始创建了一个新的 WinForms 项目。然后我在该解决方案中创建了两个新项目。我将我的两个“最低级别”项目中的所有代码和资源(不是项目文件)复制到两个全新的项目中(我通过将文件和文件夹从资源管理器拖放到 Visual Studio 中的项目中来做到这一点)。
The lowest project, let's call it B, did not reference any other project. The next project, A, referenced Bonly. So once I added the required .NET and external assembly references to the projects then the solution would build.
最低的项目,我们称之为B,没有引用任何其他项目。下一个项目A仅引用了B。因此,一旦我将所需的 .NET 和外部程序集引用添加到项目中,就会构建解决方案。
I then had my new WinForm project reference Aand did a full build. So the ref chain is:
然后我有了我的新 WinForm 项目参考A并进行了完整构建。所以参考链是:
WinForm-> A-> B
WinForm-> A-> B
I then modified WinFormonlyand did a standard build (F6). As before, Visual Studio rebuilt all three projects.
然后我只修改了WinForm并进行了标准构建 (F6)。和以前一样,Visual Studio 重建了所有三个项目。
After some systematic eleminiation of source files in project BI found that if I removed my Resources.Designer.cs
and Resources.resx
(and commented out the code that made use of the .Properties.Resources
object of those resources) then a modification of WinFormwould no longer rebuild the entire solution and would only rebuild WinForm.
在对项目B 中的源文件进行一些系统的消除后,我发现如果我删除了我的Resources.Designer.cs
和Resources.resx
(并注释掉了使用.Properties.Resources
这些资源对象的代码),那么对WinForm的修改将不再重建整个解决方案,只会重建赢形式。
Adding the Resources.resx
and Resources.Designer.cs
back to project B(but leaving the referenced code commented out so that nothing was making use of the resources) would re-introduce the full build behavior.
将Resources.resx
和Resources.Designer.cs
重新添加到项目B(但将引用的代码注释掉,以便没有使用资源)将重新引入完整的构建行为。
To see if perhaps my resource files were corrupted, I deleted them again and then created a new one (via Project Properties -> Resources) and re-added the same resource as before, which was a single Excel file. With this setup the full rebuild would still occur.
为了查看我的资源文件是否已损坏,我再次删除了它们,然后创建了一个新资源文件(通过项目属性 -> 资源)并重新添加了与以前相同的资源,即单个 Excel 文件。使用此设置,仍会发生完全重建。
I then removed the single resource, but left the resource file in project B. Even with no resources added, but the resource file still in the project, the full (unneeded) rebuild would occur.
然后我删除了单个资源,但将资源文件留在了项目B 中。即使没有添加资源,但资源文件仍在项目中,也会发生完全(不需要的)重建。
It appears that just having a resource file added to a (.NET 3.5) project will cause Visual Studio 2010 to always rebuild that project. Is this a bug or intended/expected behavior?
似乎只是将资源文件添加到 (.NET 3.5) 项目将导致 Visual Studio 2010 始终重建该项目。这是错误还是预期/预期行为?
Thanks all again!
再次感谢大家!
采纳答案by Matt Klein
While I don't think this is a fix, it is a workaround that has worked for my situation...
虽然我不认为这是一种解决方法,但它是一种适用于我的情况的解决方法......
I originally had about 5 projects out of 50 that contained a Resources
section. These projects would always be rebuilt and thus anything that they depended on would also be rebuilt. One of those 5 projects was a "base" level library that 48 of the other projects referenced, thus 96% of my project would be rebuilt every time even if it didn't need it.
我最初有 50 个项目中的大约 5 个包含一个Resources
部分。这些项目总是会被重建,因此它们所依赖的任何东西也会被重建。这 5 个项目之一是一个“基础”级别的库,其他 48 个项目引用了该库,因此即使不需要我的项目,每次都会重建 96%。
My workaround was to use dependency injection, interfaces, and a dedicated "Resources" project. Instead of having those 5 projects reference their own Resources
object, I created an interface in each project that would supply the desired resources. Then, the classes that needed those resources would require that interface be passed in during their creation in the constructor (constructor injection).
我的解决方法是使用依赖注入、接口和专用的“资源”项目。我没有让这 5 个项目引用它们自己的Resources
对象,而是在每个项目中创建了一个接口来提供所需的资源。然后,需要这些资源的类将要求在构造函数中创建时传入该接口(构造函数注入)。
I then created a separate "Resources" project that had an actual Resources section like normal. This project only contained the resources themselves, and a class for each interface that was needed to provide those resources via an interface. This project would reference every other project that had a resource dependency and implement the interface that the project needed.
然后,我创建了一个单独的“资源”项目,该项目具有正常的实际资源部分。该项目仅包含资源本身,以及通过接口提供这些资源所需的每个接口的类。该项目将引用具有资源依赖关系的所有其他项目,并实现该项目所需的接口。
Finally, in my "Top Level" project which nothing referenced (and where the exe was actually built and my composition root lives) I referenced the "Resources" project, wired up the DI, and away we went.
最后,在我没有任何引用的“顶级”项目(以及实际构建 exe 和我的组合根所在的位置)中,我引用了“资源”项目,连接了 DI,然后我们就走了。
This means that only two projects (the "Resources" and the "Top Level") will be rebuilt every time, and if I do a partial build (Shift-F6) then they won't get rebuilt at all.
这意味着每次只重建两个项目(“资源”和“顶级”),如果我进行部分构建(Shift-F6),那么它们根本不会被重建。
Again, not a great work around, but with 48 projects being built every time a build would take about 3 minutes, so I was losing 30 to 90 minutes a day with needless rebuilds. It took awhile to refactor, but I think it was a good investment.
同样,这不是一个很好的解决方法,但是每次构建需要大约 3 分钟,因此要构建 48 个项目,因此我每天因不必要的重建而损失 30 到 90 分钟。重构需要一段时间,但我认为这是一项不错的投资。
Here is a simplified diagram. Note that the dependencies from Main.exe
to Proj1
and Proj2
are not shown in order to reduce clutter.
这是一个简化的图表。请注意,为了减少混乱,没有显示Main.exe
toProj1
和的依赖关系Proj2
。
With this design, I can do a build of Proj1
or Proj2
without triggering a full rebuild, since they don't have any dependencies on a Resources
section. Only Main
knows about the Resources
implementation.
使用这种设计,我可以执行Proj1
或Proj2
不触发完全重建的构建,因为它们对某个Resources
部分没有任何依赖性。只Main
知道Resources
实现。
回答by Ryan Byrne
Here is an answer from VS2010 always rebuilds solution?
This issue is solved by changing the project files, cleaning solution, deleting all bin folders by hand, restarting Visual studio and rebuilding everything.
这个问题是通过更改项目文件、清理解决方案、手动删除所有 bin 文件夹、重新启动 Visual Studio 并重建所有内容来解决的。
回答by Owen Wengerd
Based on your observations, it sounds like you have projects expressing dependencies to other projects in a way that isn't obvious. It is possible for orphaned dependencies to remain in project files without being apparent in the UI. Have you looked through a misbehaving project file after opening it in a text editor? Checked solution build dependencies?
根据您的观察,听起来您的项目以不明显的方式表达对其他项目的依赖。孤立的依赖项可能会保留在项目文件中,而不会出现在 UI 中。在文本编辑器中打开一个行为不端的项目文件后,您是否查看过它?检查解决方案构建依赖项?
If you're not able to spot anything, try recreating one of your projects from scratch to see if the new project exhibits the same problem. If the clean project builds correctly, you'll know that you have unwanted dependencies expressed somewhere. As far as I know, these would have to be in the project file(s) or the solution file, unless you have makefiles or other unusual build steps.
如果您无法发现任何问题,请尝试从头开始重新创建您的项目之一,以查看新项目是否存在相同的问题。如果干净的项目构建正确,您就会知道在某处表达了不需要的依赖项。据我所知,除非您有 makefile 或其他不寻常的构建步骤,否则这些必须在项目文件或解决方案文件中。
回答by Yochai Timmer
This happens when a project has a file that doesn't really exist.
The project can't determine if the file was changed (because it's not there) so it rebuilds.
当项目有一个实际上并不存在的文件时,就会发生这种情况。
项目无法确定文件是否已更改(因为它不存在),因此它会重建。
Simply look at all the files in the project, and search for the one that doesn't have an expandable arrow near it.
只需查看项目中的所有文件,然后搜索附近没有可展开箭头的文件。
回答by PhonPanom
I had the same issues with you. I found that it came from some deleted files. When I had removed the files from my project, the issues was gone. Regards.
我和你有同样的问题。我发现它来自一些已删除的文件。当我从我的项目中删除文件时,问题就消失了。问候。
回答by user3285954
Open Tools - Options, select Projects and Solutions - Build and Run in tree, then set "MSBuild project build output verbosity" to Diagnostic. This will output the reason for building a project, i.e.
打开工具 - 选项,选择项目和解决方案 - 在树中构建和运行,然后将“MSBuild 项目构建输出详细程度”设置为诊断。这将输出构建项目的原因,即
Project 'ReferencedProject' is not up to date. Project item 'c:\some.xml' has 'Copy to Output Directory' attribute set to 'Copy always'.
项目“ReferencedProject”不是最新的。项目项“c:\some.xml”的“复制到输出目录”属性设置为“始终复制”。
or
或者
Project 'MyProject' is not up to date. Input file 'c:\ReferencedProject.dll' is modified after output file 'c:\MyProject.pdb'.
项目“MyProject”不是最新的。输入文件 'c:\ReferencedProject.dll' 在输出文件 'c:\MyProject.pdb' 之后被修改。
In this case the fix is to copy some.xml only if newer.
在这种情况下,修复方法是仅在较新时才复制 some.xml。
Pre and post build events can trigger build as well.
构建前和构建后事件也可以触发构建。
回答by Ofek Shilon
For this category of build problems setting MSBuild output verbosity to 'diagnostic' is indeed a necessary first step. Most of the time the stated reason for the re-builds would be enough to act upon, BUT occasionally MSBuild would erroneously claim that some files are modified and need to be copied.
对于此类构建问题,将 MSBuild 输出详细程度设置为“诊断”确实是必要的第一步。大多数情况下,重新构建的所述原因足以采取行动,但偶尔 MSBuild 会错误地声称某些文件已被修改并需要复制。
If that is the case, you'd need to either disable NTFS tunneling or duplicate your output folder to a new location. Here it is in more words.
如果是这种情况,您需要禁用 NTFS 隧道或将输出文件夹复制到新位置。 这里是更多的话。
回答by I-A-N
In my case the culprit was "Copy Local" setting of a referenced dll set to true and "Copy to Output Directory" setting a file set to Copy always.
在我的情况下,罪魁祸首是引用的 dll 的“复制本地”设置为 true 和“复制到输出目录”将文件设置为始终复制。
回答by Michael Logutov
I had the same issue in VS 2015.
我在 VS 2015 中遇到了同样的问题。
What did the trick for me is:
对我来说有什么窍门是:
- One project was referencing itself copy in some other project bin (magic, yes). This kind of stuff could be found when switching to diagnostic build output (in build options) and then trying to build projects one by one from the top of projects hierarchy - if you see the project that rebuilds even if nothing has been changed then see it's references.
- I've changed all "copy always" files in all projects to "copy if newer". Basically, in all .csproj files replace
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
to<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- Then I've disabled NTFS tunneling as described in thisarticle with this powershell script:
- 一个项目在其他项目库中引用自己的副本(魔术,是的)。当切换到诊断构建输出(在构建选项中)然后尝试从项目层次结构的顶部一个一个地构建项目时,可以找到这种东西 - 如果您看到即使没有任何更改也重建的项目,那么看到它是参考。
- 我已将所有项目中的所有“始终复制”文件更改为“如果更新则复制”。基本上,在所有 .csproj 文件中替换
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
为<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- 然后,我一直在描述禁用NTFS隧道这条与此PowerShell脚本:
New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "MaximumTunnelEntries" -Value 0 -PropertyType "DWord"
New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "MaximumTunnelEntries" -Value 0 -PropertyType "DWord"
After that I needed on rebuild and it seems working for now.
之后我需要重建,现在似乎可以正常工作。
回答by Mikhail
Another problem that frequently happens is when some item in your solution has a modified stamp that is in the future. This can happen if you set your clock forward, and then set your clock to the correct time. I had this happen while installing Linux.
另一个经常发生的问题是当您的解决方案中的某些项目具有将来的修改标记时。如果您将时钟调快,然后将时钟调到正确的时间,就会发生这种情况。我在安装 Linux 时发生了这种情况。
In this case you can recursively touch all the files using git bash (yes, in Windows):
在这种情况下,您可以使用 git bash 递归地访问所有文件(是的,在 Windows 中):
find . -exec touch {} \;