Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine the source of an indirect dependency on incorrect .NET Framework version

I would like to know how I can determine the source of this build error;

Warning 4   The primary reference "MyNamespace.MyProject" could not be resolved because 
   it has an indirect dependency on the .NET Framework assembly "System.Xml, Version=4.0.0.0,
   Culture=neutral, PublicKeyToken=b77a5c561934e089" which has a higher version "4.0.0.0" than
   the version "2.0.0.0" in the current target framework.   MyNamespace.MyOtherProject

I understand the meaning of this error (and the 5 others like it for this same project), but I cannot work out how to resolve it in my case. The 'primary reference' in this case (MyNamespace.MyProject) has no direct dependencies on .NET 4.0.x.

The primary reference depends on only one other project of mine (MyNamespace.MyCoreProject), which the source project for the build (MyNamespace.MyOtherProject) also depends directly on. And the build is not complaining about that project having indirect references to .NET 4.0.x, so I assume I can rule that out.

The primary reference has a direct dependency on three (3) 3rd party DLLs, all of which also Target .NET 2.0.

I have employed dotPeek to examine the built libraries, and cannot see any reference to anything using .NET 4.0.

The only other potential spanner in the works is the use of PostSharp, which is directly referenced by 'MyNamespace.MyCoreProject' (referenced by the primary reference project), which may be causing the problem, as I believe there is a related VS2010 bug when referencing PostSharp.dll (http://www.sharpcrafters.com/forum/Topic4444-4-1.aspx#bm4462), however I also removed that from the build chain and still see this error, so I assume I can also rule that out.

If someone can tell me why this is happening, fantastic! If not, some direction on how to work out what the unnamaed 'indirect reference' is would be just as helpful!

Incidentally, I have tried all of the following tools to get some info, but they're not telling me much I didn't already know (which is the direct dependencies of the DLL in question); - .NET Reflector - dotPeek - IldAsm - Depends (Dependency Walker)

like image 845
RJ Lohan Avatar asked Jun 06 '12 00:06

RJ Lohan


2 Answers

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;

  1. 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
  2. Setting 'Specific Version' to true in the build did nothing to fix this
  3. 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!

like image 142
RJ Lohan Avatar answered Oct 06 '22 02:10

RJ Lohan


Try to use MSIL Disassembler tool for all suspicious assemblies.

  1. 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)
  1. 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.CompilationRelaxationsAttribute

  2. Investigate 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

like image 27
Dmitry Harnitski Avatar answered Oct 06 '22 02:10

Dmitry Harnitski