Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

MSBuild: MSB3275 warning, GAC and .NET version

, 5 Jan 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
In this post I will describe you an interesting problem that my colleague ran into at work.

In this post I will describe you an interesting problem that my colleague ran into at work. His original VS solution consisted of two projects targeting .NET 3.5 – let’s name them Alpha and Beta. Alpha had a direct reference to Beta and thus depended on it. Beta was using NHibernate, Castle.Core and some other libraries. When compiling Alpha he received:

c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1360,9): warning MSB3258: The primary reference "PathToBeta.dll" could not be resolved because it has an indirect dependency  on the .NET Framework assembly "mscorlib, 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.

and the whole build failed with:

Error 3 The name 'Beta' does not exist in the current context

At first sight we thought that the problem lied within the Beta project configuration and we checked its target framework (v3.5) and platform (AnyCPU). Everything seemed to be fine so the next step was to enable a detailed MSBuild log and see whether it will tell us more about what was going on. To set the MSBuild build output verbosity open the Options… dialog in Visual Studio and then choose Build and Run settings:

MSBuild output settings

After a rebuild we could see that the Csc MSBuild task was missing /reference to the Beta.dll assembly and thus failed at compilation (I dotted unimportant parts):

2>Task "Csc"
2>  C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702,2008 /nostdlib+ /platform:AnyCPU /errorreport:prompt /warn:4 /define:DEBUG;TRACE /errorendlocation /preferreduilang:en-US /highentropyva- /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\Alpha.exe /target:exe /utf8output ...
2>  Microsoft (R) Visual C# Compiler version 4.0.30319.17929
2>  
2>  for Microsoft (R) .NET Framework 4.5
2>  Copyright (C) Microsoft Corporation. All rights reserved.
2>  
2>...\Program.cs(13,31,13,39): error CS0103: The name 'Beta' does not exist in the current context
2>  The command exited with code 1.
2>Done executing task "Csc" -- FAILED.

Our next question was why MSBuild did not provide this reference? To answer this we needed to examine a part of the MSBuild log that described the Beta project compilation process, in particular lines produced by the ResolveAssemblyReferences MSBuild task. For the Castle.Core library reference resolution we had a following log:

Dependency "Castle.Core, Version=2.5.1.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc".
      Resolved file path is "...\SharedAssemblies\Castle.Core.dll".
      Reference found at search path location "...\SharedAssemblies".
          For SearchPath "...\SharedAssemblies".
          Considered "...\SharedAssemblies\Castle.Core.exe", but it didn't exist.
      Required by "Beta ...".
      Found related file "...\SharedAssemblies\Castle.Core.xml".
      This reference is not "CopyLocal" because it's registered in the GAC.

The last line is extremely important – it says that the referenced assembly won’t be copied to the output folder because it is registered in the GAC. I checked the GAC on the colleague’s computer and found following Castle.Core registrations:

> gacutil /l Castle.Core
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.17929
Copyright (c) Microsoft Corporation.  All rights reserved.

The Global Assembly Cache contains the following assemblies:
  Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL
  Castle.Core, Version=1.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL
  Castle.Core, Version=2.5.1.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL

Number of items = 1

Unfortunately gacutil does not say which versions of .NET those assemblies are targeting so we needed to check this out on our own. If you have .NET2.0/3.5 and .NET4.0/4.5 installed on your machine then you also have two GAC folders created. Assemblies targeting .NET2.0/3.5 will land in C:\Windows\assembly, while assemblies targeting .NET4.0/4.5 in C:\Windows\Microsoft.NET\assembly. Interestingly it seems that during assembly resolution assemblies registered in the .NET4.0/4.5 GAC take always precedence over assemblies with the same version registered in the .NET2.0/3.5 GAC – even if the calling application targets .NET2.0/3.5. Moving back to our case I found Castle.Core assembly (v2.5.1.0) in the C:\Windows\Microsoft.NET\assembly folder and run corflags on it (just for sureSmile | :) ):

> corflags Castle.Core.dll

Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  4.0.30319.17929
Copyright (c) Microsoft Corporation.  All rights reserved.

Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32
CorFlags  : 0x9
ILONLY    : 1
32BITREQ  : 0
32BITPREF : 0
Signed    : 1

Uninstalling Castle.Core 2.5.1.0:

gacutil /u Castle.Core,Version=2.5.1.0,Culture=neutral,PublicKeyToken=407dd0808d44fbdc

resolved all the compilation issues: MSBuild started using Castle.Core.dll from the Shared folder and the Csc task finally received its missing /reference Beta.dll argumentSmile | :) .

If you would like to reproduce this issue on your machine (or you are interested in experimenting with GAC) I prepared a sample VS solution that consists of three projects (two libraries: TestLib1, TestLib2 and a console application: TestApp). TestApp references TestLib1 and TestLib1 references TestLib2 and all projects target .NET3.5. On the first compilation everything should work just fine. Now, change the TestLib2 Target Framework (in the project properties dialog) to .NET4.0, compile it (only TestLib2) and install with gacutil:

..\TestLib2\bin\Debug\> gacutil /i TestLib2.dll

Then switch the TestLib2 Target Framework back to .NET3.5 and try to compile the solution. You should receive the same MSBuild warning and failed notice as my colleague. Happy diagnosingSmile | :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sebastian Solnica
Software Developer (Senior)
Poland Poland
Interested in tracing, debugging and performance tuning of the .NET applications (especially ASP.NET).
 
If you find this article interesting, maybe you would like to pay me a visit: http://lowleveldesign.wordpress.com? Smile | :)

Comments and Discussions

 
QuestionSolved! PinmemberCODEISZ22-Jun-13 12:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141220.1 | Last Updated 5 Jan 2013
Article Copyright 2013 by Sebastian Solnica
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid