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

8

19

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)

Outweigh answered 6/6, 2012 at 0:2 Comment(6)
Just because it doesn't reference any 4.0 code, doesn't mean it doesn't need the 4.0 binary to run.Holifield
@ColeJohnson If nothing depends on 4.0 framework, then I don't need 4.0 framework. I'm trying to find out what it is that is requiring 4.0.Outweigh
Have you gone to the properties of the project and changed the dependent framework?Holifield
That look like you have a project built against .net2 that is referencing some v4 assemblies. Look thru references check the properties for each one of them one or more will be v4. Remove and replace with the .net 2 version.Thorianite
@ColeJohnson everything in my code is targeting 3.5 (which is .NET 2.0 CLR).Outweigh
@TonyHopkinson, Correct, that's what the error message says. However I can't find what is using System.Xml v4.0.0.0 - that's the whole point of the question.Outweigh
O
7

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!

Outweigh answered 7/6, 2012 at 0:26 Comment(2)
how do you solve it using gacutil then? It does requires an argument in command prompt.Berniecebernier
what exactly is "assembly display name"? the whole thing through the public key token?Purnell
B
2

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

Blakeslee answered 6/6, 2012 at 3:55 Comment(5)
Thanks, I've given that a look, but it doesn't tell me much more than several other tools do; it lets me see the direct dependencies, (none of which target 4.0) but no further than that. In fact, it doesn't seem to tell me which framework is targeted by a particular assembly either. The version you point out is just the assembly version, which doesn't necessarily relate to the .NET framework it requires.Outweigh
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 targetBlakeslee
Yes I'm working through that now, but it's not really throwing me many clues, and it's a bloody long log file (6.5million lines!)Outweigh
There should be some reference to .net 4.0 dll. It may be very undirect but it should be. Try to find this substring "System.Xml, Version=4.0.0.0" and follow the pathBlakeslee
there is no such string in the log (except to report the error) and that's half the problem. That file is NOT referenced by any of my code, or indeed by any of the references referenced by my code! See my answer below for my 'solution'.Outweigh
P
2

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.

Porcine answered 6/12, 2013 at 1:17 Comment(0)
W
2

In my case, the assembly was uninstalled and all references (to my knowledge) were removed.

Found it in the app.config:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            ...
        </dependentAssembly>
    </assemblyBinding>
</runtime>     

Deleted the dependentAssembly and got my app working again.

Weidar answered 20/12, 2016 at 5:48 Comment(1)
It was app.config all along for me. I had removed all references to a library and anything which might have linked to a library and still build would complain that it couldn't find the library... the one I had expunged from my system and was completely unnecessary. I even tried to force all projects to use an explicit lower version of it, still failing. The project files were clean. No trace... except for app.config. No idea why, but app.config decided that it needed to use this library. It would have been great had the Diagnostic Build Logs told me that was why.Autoerotic
L
1

I also had this problem, and event.er lead me to the solution. I had the following in my app.config:

  <dependentAssembly>
    <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="4.0.0.0" />
  </dependentAssembly>

I changed newVersion to "2.0.0.0" and the solution built.

Lauds answered 8/2, 2017 at 9:4 Comment(0)
E
0

My guess is the 3rd party DLL is the one that does not have specific version set to true for it's dependencies and is causing your problem.

Euraeurasia answered 24/9, 2013 at 1:6 Comment(0)
C
0

I was having problems with System.Data.SQLite.dll in a project targeting .NET 4.5 which turned out to be that a version targeting 4.5.1 was installed to GAC_32.

If I built the solution with Copy Local = True, all would be well. But as I was embedding the SQLite assemblies in the final build this seemed unnecessary and I wanted to sort it out.

I tried running gacutil -u System.Data.SQLite.dll but had trouble with it so in the end I just used Windows' Programs And Features to uninstall it and then all was well.

Calia answered 7/9, 2018 at 18:20 Comment(0)
L
0

If using Visual Studio 2019 and trying to build .NET 3.5 projects this will help.

Visual Studio service packs and the newer Visual Studio 2019 puts a program (usually WebDeploy) in Program Files and puts this folder high in the assembly probing path for your machine (so the net45 JSON.NET assembly gets picked up before any other one).

To figure out where your one is being resolved from, just use SysInternals Process Monitor and filter on the referenced DLL. Then kick off your build. Process Monitor will tell you where it's resolving that assembly from and it's usually the one in a WebDeploy folder for VS2019 installations. You can purge the folder if you're not using the WebDeploy tool.

Specifically, for my case, I removed C:\Program Files\IIS\Microsoft Web Deploy V3\Newtonsoft.Json.dll and my build worked.

Lichenin answered 2/9, 2020 at 0:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.