Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

MSBuild: MSB3275 Warning, GAC and .NET Version

4.00/5 (1 vote)
5 Jan 2013CPOL3 min read 26K  
MSBuild: MSB3275 Warning, GAC and .NET Version

In this post, I will describe 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 the 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 the 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 always take 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 to be 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 did. Happy diagnosing.

License

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