Related
Ever since I've been using the (relatively) new .NET Standard Library project type in Visual Studio, I've been having some problems getting a complete set of DLL files that are required by my project.
The problem is usually limited to 3rd-party libraries which I reference as NuGet packages. I've noticed that these don't get copied to the output folder of my project when I build it. This didn't use to be the case in classic project types.
While I can appreciate the de-cluttering effect that this change has brought for .NET Standard projects, I'm now faced with a problem. I sometimes absolutely need to be able to get the entire list of all files that my project depends on!
I have several different cases, where I might require this list for one reason or another, but the one I believe is most crucial for me, is when I want to gather these files from the csproj itself, right after it's built. In there, I have a custom MSBuild <Target> which should take all the files from the output dir and zip them together for distribution. The problem is, I'm missing all the files that come from NuGet dependencies, because they're not there!
How can I solve this in a general (i.e. not project-specific) way?
UPDATE
There's this deps.json file that contains basically all I'm after and then some. It's just a matter of extracting the relevant information and find the files in the local NuGet cache. But that would involve writing a specialized app and calling it from my target. Before I start writing one myself... Is there something like this already out there somewhere?
I followed this answer and it sort of works.
The suggested thing was to include the following into my csproj:
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
My main concern is that it also outputs some other DLLs from the framework (such as System.Memory.dll and System.Buffers.dll, among others), which I didn't expect. But maybe that's a good thing. They do seem to be dependencies, just not direct ones. I'll see how it plays out.
If it turns out ok, my only wish would be that this directive was more prominently displayed in project settings (as a simple checkbox, maybe?) so I wouldn't have to hunt the web to find it.
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.
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.
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.
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.
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).
The lowest project, let's call it B, did not reference any other project. The next project, A, referenced B only. So once I added the required .NET and external assembly references to the projects then the solution would build.
I then had my new WinForm project reference A and did a full build. So the ref chain is:
WinForm -> A -> B
I then modified WinForm only and did a standard build (F6). As before, Visual Studio rebuilt all three projects.
After some systematic eleminiation of source files in project B I 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 WinForm would no longer rebuild the entire solution and would only rebuild 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.
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.
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.
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?
Thanks all again!
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.
Project 'ReferencedProject' is not up to date. Project item
'c:\some.xml' has 'Copy to Output Directory' attribute set to 'Copy
always'.
or
Project 'MyProject' is not up to date. Input file
'c:\ReferencedProject.dll' is modified after output file
'c:\MyProject.pdb'.
In this case the fix is to copy some.xml only if newer.
Pre and post build events can trigger build as well.
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.
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).
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.
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.
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.
Here is a simplified diagram. Note that the dependencies from Main.exe to Proj1 and Proj2 are not shown in order to reduce clutter.
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.
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.
I had the same issue in 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 this article with this powershell script:
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.
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.
For .Net Core Projects, all solutions above are not working.
I've found the solution. In case you are using Visual Studio 2019:
Build the solution twice
Turn on Tools -> Options -> Projects and Solutions -> SDK-Style Projects -> Logging Level -> Verbose
Clear the output window
Build your start project
Inspect the output window. All the string starting with FastUpToDate
You will find some project items that are making your project not up to date.
Fix these issues and try again from step 1. If your fixes are correct, you will achieve Build: 0 succeeded, 0 failed, {n} up-to-date, 0 skipped in the last string of build output.
The MSBuild team is collecting documentation about investigating build incrementality issues here:
https://github.com/Microsoft/MSBuild/wiki/Rebuilding%20when%20nothing%20changed
UPDATED LINK: https://github.com/dotnet/msbuild/blob/main/documentation/wiki/Rebuilding-when-nothing-changed.md
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?
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.
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.
In this case you can recursively touch all the files using git bash (yes, in Windows):
find . -exec touch {} \;
I've finally found one more culprit that I had hard time finding by increasing the build log verbosity.
In some cases, MSBuild looks for vc120.pdb in the output folder, and if this file doesn't exist, it will rebuild the entire project. This occurs even if you have disabled debug symbol generation.
The workaround here is to enable debug symbols and let this file get generated, then disable the setting again without deleting the PDB file.
I had this same problem and it turned out to be related to a couple of project that had a copy local reference to a dll in their own output directory.
The key to finding this was having diagnostic output set for the build output, but also knowing what to look for in the log. Searching for: 'not up to date' was the key.
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.
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.
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.
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.
I had the problem of Visual Studio rebuilding projects when upgrading from Visual Studio 2015 to 2017 and I add this answer for the benefit of those who might experience similar problems, as it does not seem to be documented anywhere.
In my case, the problem was that all projects in the solution had the same intermediate Output path (obj). The file GeneratedInternalTypeHelper.cs gets generated by all projects containing XAML. Up to Visual Studio 2015, the build process apparently did not check for the file date of this file and thus no problem with it occurred. With VS2017 the file date of this file is checked and because a later project in the build process will overwrite it (with the same content), the earlier project will re-build, re-triggering the later build, ad infinitum.
The solution in this case is to ensure that all projects have differing intermediate output directories, which will make the problem go away.
In my case (mixed C#, C++/CLI and native C++ solution) , some C++ projects were being re-linked even if nothing had changed. I spent ages trying to work out what was happening. In the end I worked out from the "Command Line" option that the PDB output path (option /Fd) could not handle the folder setting $(IntDir). I removed that - an empty value will do the default correctly - and my issue went away.
As others have noticed, a likely reason is that CopyToOutputDirectory is set to Always. This can be fixed simultaneously in all project files by applying the powershell script below:
$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
}
Files that do not exist are a problem and obviously files producing no output as well. That can happen, wenn you have a resource file in a static library. (C++)
The RC class is not linked to a database, it is a simple class. The class is at only one place and is not partial. The AĆ©rochem.Domain dll project compiles just fine.
Note: If I select one of the two identical namespaces in the quick fix menu, it does nothing.
Note2: This happens to a couple of classes (some related to a database, some not)
Is there a fix to that or a way to figure what's wrong?
I had the same problem. I use ReSharper. The solution to my problem was not cleaning the solution but deleting the suo-file.
Hope that helps.
As for the reference of any future users: This thread covers four answers whereas two are in the comments. I have faced the issue several times, three of these answers have helped me in the past, so if you face the same issue, try any of these:
Clean and/or Rebuild the Solution then reanalyze the files in Resharper.
Restart Visual Studio then reanalyze
Delete the bin/ folder then reanalyze
(Apparently deleting the suo-file can help, too, although I never had to do that and can't understand how it should help)
A combination of the three above.
(This is not really a new answer, it is more of a comment on the variety of answers and comments found - it is a community wiki so feel free to adapt it if necessary)
For ReSharper users that, like me, don't want to delete their solution's *.suo file:
Clear your caches via: ReSharper -> Options -> Environment -> General -> Clear Caches!
Thanks go to AUSTX_RJL for his comment to this answer. I wanted to give his valuable info more visibility.
The .dll was already in my /bin folder.
When I deleted it, it got rid of this error.
I had this problem and also ReSharper installed on visual studio.
I open bug ticket on ReSharper tracker and the development team advised me to do:
Solution:
This problem can be solved by removing the Solution User Options (.Suo) File. This file is stored in the project root but is hidden. you need to check Folder Options-> View-> Show hidden files, folders, drives. and you need to close visual studio if you have open this project because is used by visual studio.
I had the same problem while two packages were ambiguously referencing the same dll, and this is what worked for me:
I have given an alias name to one of the packages (named Dapper.StrongName), by putting the following into my .csproj file:
<Target Name="ChangeNameAlias" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
<ItemGroup>
<ReferencePath Condition="'%(FileName)' == 'Dapper.StrongName'">
<Aliases>AliasName</Aliases>
</ReferencePath>
</ItemGroup>
</Target>
And then added the namespace as using AliasName::Dapper;
I added a post here: Ambiguous extension methods
See related articles:
extern alias (C# Reference)
:: operator (C# Reference)
C# 2.0: Using different versions of
the same dll in one application
For me it was because I had referenced the DLL both by Project reference and Assembly reference. Deleting the Assembly reference fixed the issue.
If your project structure contains more than one project under one solution, then you have to delete the content of the bin folder in every project. Doing so solved the error that i was facing.
In my case, i have referenced the proyect X inside itself. So the problem wasn't ReSharper (but it was ReSharper who added the reference...)
I had this problem in a .NET standard project (I call it the host project). The namespace causing the problem was in another referenced project (which was also a .NET standard project) in the same solution.
I did everything: clean, delete resharper cache, close soln, delete .suo, delete binaries. Nothing seemed to work.
Then I converted the host project to .NET framework and then the problem disappeared.
I know this is a pretty old issue, but maybe this will help someone. If using c# razor in Asp.Net Core 2+, if you have this problem.
1) Copy the content of the file to notepad.
2) Delete the .cshtml file.
3) Create the .cshtml file with the same name.
4) Copy the content from notepad into the new file
I don't know if this is just a weird bug, or a consequence of upgrading a project from Core 1.0 to 2+, but it FINALLY fixed the problem for me. This was an issue for me in both Visual Studio 2017 and 2019.
I had this issue in Rider, and going to File | Invalidate Caches | Invalidate and Restart fixed it for me
I just opened a solution from TFS using Visual Studio 2010. The solution contains more than 100 projects (if up to me, it would probably be less than 5) and many of them happen to miss a reference (to Unity dll's).
Is there any way to simplify the fixing of these references? Now I have to delete and re-add all of them manually. Hassle.
Any suggestions would be appreciated.
To fix the problem you need to find out from where it tries to load the files. You can do so looking in the project csproj file. You either have newer (or different) versions of the assemblys installed or you have a different file and folder structure. You need to recreate the file and folder structure that has been used in that project or rewrite the csproj file to the new location.
For the future you might want to change how 3rd party references are handled. I have good experiences using this approach: Define a ThirdPartyLibraries Folder where all those libraries go and check it in. It should be in the solution folder. Everybody has to put 3rd party libs in there from now on and use them instead.
Might want to check out resharper, it might do what you need for references. I know it helps optimize and identify references in classes, not sure at the project level. Resharper has a 30 day trial
You can add all those binaries in to Binaries folder and add in to your TFS.
Now add the binaries as existing item in your solution items, so that when you open the solution it fetches all the solution items as well.
Make sure the references are added from the binaries folder.
If the location of the referenced assembly has changed, then it is relative simple to do a Find and Replace in files on the .csproj files to replace the broken reference with the correct one.
I'm currently in the process of stripping down, refactoring and cleaning up a medium sized (15 ish projects) Visual Studio solution. The solution contains projects in both C++ and C#.
I'm keen to keep things as neat as possible in terms of output - seperating anything compiler created from source code, as it helps subversion (okay, I can tell it to ignore files, but I still feel it's messy) from freaking out.
The output I would like to achieve is as follows:
SolutionDir/
SolutionDir/src/project1/{ Code here }
SolutionDir/int/project1/configuration/{.obj files and other misc compiler junk here}
SolutionDir/bin/project1/configuration/{The fun stuff goes here}
This seems trivial with C++ projects as you can specify both the output and the intermediates directory. However with C#, at least through the Visual Studio 2008 User Interface it seems impossible to move the obj directory?
After doing some digging, I added
<IntermediateOutputPath>..\..\int\ProjectName\Debug\</IntermediateOutputPath>
to the C# .csproj
This appears to work, sort of. It's true the intermediates appear to end up there, but a directory 'obj' and under it a configuration directory (e.g. 'debug') and then a 'TempPE' directory are created in the old location - all of which are empty.
This isn't really a big deal, but it would be nice to know the cause of this behavior and if possible a way to fix it.
Thanks in advance!
If you add both of the following lines to each build configuration then the "obj" folder is not created by default and there is no need for a post-build action:
<IntermediateOutputPath>Assembly\obj\Debug\</IntermediateOutputPath>
<BaseIntermediateOutputPath>Assembly\obj\Debug\</BaseIntermediateOutputPath>
SVN / SCC ignore properties are also useful if desired
I've been searching for a solution for this problem myself, and came up with something less intrusive.
Create a bat file named "CleanSrcDir.bat" somewhere (i placed mine in my project path) with the following contents:
rmdir /S /Q %1obj
SET %ERRORLEVEL%=0
After this, add something similar to the C# project's post-build events:
$(ProjectDir)CleanSrcDir.bat $(ProjectDir)
(This assumes you placed your bat file in the project directory, of course.)
Then change the post-build settings to "Always", and you're done.
It's a little hackish, but sure makes the version control problem go away.
I'd recommend adding directories that you want to ignore to an SVN ignore property one-level-up. Also, when you do an initial commit and don't add bin and obje directories, SVN clients won't freak. On another note, consider placing generated files into GeneratedFiles subdirectory of your project, and not checking that directory into SVN.