Determine the source of an indirect dependency on incorrect .NET Framework version
Whilst I have not actually worked out a good way to actually solve the problem of determining how MsBuild determines the references it uses (why it does not just tell me how it comes up with these indirect references, instead of making me guess I don't know...) I have solved my problem.
In the end, I basically removed all references in the 'primary reference' project, (which required excluding all code piece by piece - a somewhat painful process) to determine that the source of the supposed indirect reference to .NET 4.0 libs was caused by a 3rd party DLL that was referenced.
However, I do believe there is a bug in MsBuild behind this problem, as;
- The 3rd party DLL was referenced by 'Browse' to a specific DLL file on my machine - one that VERY EXPLICITLY depends only on .NET 2.0
- Setting 'Specific Version' to true in the build did nothing to fix this
- MsBuild appeared to be going to the GAC for a different version of this DLL and causing the incorrect reference error.
Now, another curiosity is that I've not touched or changed the relevant libs in some time, so this has just started happening for some other unrelated reason - what that may be, I don't know.
In the end, the only way I found to solve this issue was to run gacutil /u for each of the relevant libs to remove previously installed/used versions of the 4.0 libs. (There were about 40 in the package, so that was also painful! as the package's uninstaller did not remove the libs in the GAC)
This seems to have let msbuild start using the references I told it to, rather than coming up with its own idea of what 'use this file' and 'use this specific version means.
Solved, but I would have loved a cleaner way to do this!
Try to use MSIL Disassembler tool for all suspicious assemblies.
- Open Dll, click Ctr + M and go to end of the screen. You may see reference to some .NET 4 assembly like this one:
AssemblyRef #1 (23000001)
Token: 0x23000001
Public Key or Token: b7 7a 5c 56 19 34 e0 89
Name: mscorlib
Version: 4.0.0.0
Major Version: 0x00000004
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
HashValue Blob:
Flags: [none] (00000000)
Find type that is loaded from that .NET assembly usinf ref # as search criteria. This is sample of type you can find in screen
TypeRef #18 (01000012)
Token: 0x01000012
ResolutionScope: 0x23000001
TypeRefName: System.Runtime.CompilerServices.CompilationRelaxationsAttributeInvestigate why that type is used.
Update: Did you try to set set MSBuild Project Build Output Verbosity to "Detailed" on Tools\Options\Projects and Solutions\Build And Run page, and then rebuild solution? You may see something in ResolveAssemblyReference target
I had this problem and used CheckAsm to determine that one of my own assemblies for some strange reason was referring to a .NET 4.0 version of a 3rd party library, whereas the app itself was .NET 2.0. I deleted all instances of that assembly from my hard drive (there were a lot of copies lying around), rebuilt the solution and all was good.