We have a .Net 3.5 application that is built using some scripts that call msbuild.exe
Recently all our machines started automatically updating from .Net 4.0 to .Net 4.5 as part of a company-wide policty, and our build scripts started failing.
The errors given is that they cannot find a referenced assembly, like this :
error CS0012: The type 'System.Drawing.Image' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
It looks like in every case, we try to build project A that has a reference to project B, and project B has a reference to library X, and get an error that project A needs a reference to library X.
A temporary workaround is to uninstall 4.5, uninstall 4.0, then re-install 4.0, however this is time consuming and not practical in an environment where updates are often silent and automatic.
I've tried using the following msbuild switches already, with no luck
/toolsversion:3.5
- Exception about Func
being undefined/toolsversion:4.0
- Does not work because 4.5 replaced 4.0 tools/p:TargetFrameworkVersion="v3.5"
- Same error/p:VisualStudioVersion=11.0
- Same error
*` in the csproj file - Already exists, and same errorThe .csproj files already has <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
specified in every single csproj file in my solution, and ToolsVersion="4.0"
.
I have also tried changing the TargetFrameworkVersion
to 4.0, and that does not work either.
I found some notes online about Microsoft changing the flag OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration
from false
to true
during the 4.0 to 4.5 update, however manually setting that flag in the csproj files also does not fix the issue.
<OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration>
false
</OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration>
Why is msbuild failing to find these child assemblies after upgrading from 4.0 to 4.5, and how can I fix it?
Update
I've finally figured out the source of the problem, but I have no idea how this could be happening.
ProjectA has a class which inherits from an abstract class in ProjectB, and one of the properties of ProejctB.BaseClass
is of type System.Drawing.Image
.
namespace ProjectA
{
public class SomeClass : BaseClass { }
}
namespace ProjectB
{
public abstract class BaseClass
{
public System.Drawing.Image GetImage() { };
}
}
From everything I've read online, and from creating a test project of my own, this means that ProjectA needs a reference to System.Drawing.Image
in order to build.
But for whatever reason, this restriction does not seem to matter for our project when buliding with msbuild 4.0 or in VS 2010. It's perfectly happy to build ProjectA without a reference to System.Drawing.Image
.
Even after updating to .Net 4.5, I can still build ProjectA
successfully from Visual Studio 2010 without adding a reference to System.Drawing.Image
, however building using msbuild now (correctly?) fails. I also get the reference errors when building in VS 2012 Express, so whatever is allowing this to occur has apparently been fixed in newer versions of VS.
For now, I have gone through all 148 projects in our solution and fixed all the references, however I want to leave this question open to try and get an answer on why I am able to build ProjectA
using msbuild 4.0 or Visual Studio 2010 without a reference to System.Drawing.Image
.
I have already determined that I can't easily reproduce the behavior in a test project, so my best guess is its either some configuration, some part of the build scripts, or it's a bug that existed back when the .sln or .csproj files got created and no longer exists with newly created projects.
Based on Hans' comment, it sounds like something changed in the internal C# compiler between version 4 and version 5 to fix the bug that was allowing us to build ProjectA
without proper references.
This doesn't have anything to do with MSBuild, what changed is that you are using a different C# compiler. Version 5 instead 4. I've seen cursory evidence in other questions that is is more aggressive about wanting to resolve indirect type references. Nothing to nail to the wall, everybody just fixes this with the obvious solution.
When viewing the msbuild.exe
log, I can see it comes down to a call to csc.exe
, which contains the exact same /reference
list, however fails with 4.5.
Building ProjectA with 4.0
Task "Csc" c:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /define:TRACE /reference:C:\Path\bin\Release\ProjectB.dll /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.Web.Services.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:pdbonly /filealign:512 /keyfile:ProjectA.snk /optimize+ /out:obj\Release\ProjectA.dll /target:library Properties\AssemblyInfo.cs SomeFile.cs Properties\VersionInfo.cs Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1 Copyright (C) Microsoft Corporation. All rights reserved. Done executing task "Csc".
Building ProjectA with 4.5
Task "Csc" (TaskId:5812) C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /define:TRACE /highentropyva- /reference:C:\Path\bin\Release\ProjectB.dll /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.Web.Services.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:pdbonly /filealign:512 /keyfile:ProjectA.snk /optimize+ /out:obj\Release\ProjectA.dll /target:library /utf8output Properties\AssemblyInfo.cs SomeFile.cs Properties\VersionInfo.cs (TaskId:5812) Microsoft (R) Visual C# Compiler version 4.0.30319.18408 (TaskId:5812) (TaskId:5812) for Microsoft (R) .NET Framework 4.5 (TaskId:5812) Copyright (C) Microsoft Corporation. All rights reserved. (TaskId:5812) (TaskId:5812) SomeFile.cs(32,18): error CS0012: The type 'System.Drawing.Image' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. [C:\Path\ProjectA.csproj] c:\Path\bin\Release\ProjectB.dll: (Location of symbol related to previous error) (TaskId:5812) The command exited with code 1. (TaskId:5812) Done executing task "Csc" -- FAILED. (TaskId:5812)
I was hoping someone here would be able to explain what that was, and how I could reproduce this "bug" with 4.0, however it doesn't look like this question is an easy one to answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With