5

I have written an application in Visual Studio 2015 that uses C# 6.0 features and targets .NET 4.5.2. When I build it using Microsoft Build Tools 2015, which is what is done by our TeamCity server, the resulting bin folder also contains a copy of mscorlib.dll. The problem here is that the mscorlib.dll being copied is the .NET 4.6 DLL, which causes problems at runtime.

I have replaced my call to string.Format() with the new string interpolation syntax to work around the problem. That, however, shoves the underlying problem under the carpet instead of addressing it: Why is the .NET 4.6 DLL included in my build and how can I force the 4.5.2 DLL to be included in its place?

If you are interested in the runtime problem this caused for me, it caused my:

string.Format(CultureInfo.InvariantCulture, "{0}='{1}'", "key", "value")

To be interpreted as (link -- which only exists in .NET 4.6):

System.String System.String.Format(System.IFormatProvider, System.String, System.Object, System.Object)

Instead of (link):

System.String System.String.Format(System.IFormatProvider, System.String, params System.Object[])
Philip Atz
  • 886
  • 1
  • 10
  • 26
  • 2
    Trying to save a penny on a VS licenses forever causes a pound of problems. Surely the real problem is not that mscorlib.dll gets *copied*, but that you are referencing the wrong one. It *must* come from the c:\program files (x86)\reference assemblies, the ones in c:\windows\microsof.net are not correct. Targeting pack required. – Hans Passant Nov 24 '15 at 20:43
  • I have checked my .csproj files and there is no reference to an mscorlib.dll folder: they target 4.5.2 and reference a number of `System` / `System.*` namespaces. What does the targeting pack do and how will it help in this case? I am not trying to save a penny on licenses at all, as I already have VS2015 installed on my machine. The VS build works fine there and the mscorlib.dll is not included in my bin folder. The problem is when I build on my build server, where the build is performed by the Microsoft Build Tools 2015 (surely build servers are not meant to have VS installed). – Philip Atz Nov 25 '15 at 06:54
  • 1
    The targeting pack seems to resolve the issue (by not including `mscorlib.dll` at all in the build). Do you want to post it as an answer so that I can give you the points? – Philip Atz Nov 27 '15 at 15:42
  • I'm having this same issue, can you explain how to implement the solution with the targeting pack? I'm not familiar with targeting pack at all – Erica Stockwell-Alpert Sep 04 '18 at 14:26
  • @PhilipAtz We hare having the very same issue at the moment after going from .NET 4.5.1 to 5.6.1 on a project. I don't understand what do you reg. "Targeting Pack" - if you could provide some hints that would be awesome! – Markus Knappen Johansson Sep 06 '18 at 17:33
  • I have written an answer below, summarising the situation. I hope it helps! – Philip Atz Sep 24 '18 at 21:05

1 Answers1

1

When you build your solution on a TeamCity build agent, TeamCity uses a version of MSBuild that you had installed on the agent. Each version of MSBuild is created to build DLLs that target a specific version of .NET. For example, I think that MSBuild 2015 targets .NET 4.6.

In order to use MSBuild 2015 to build DLLs that target .NET 4.5.2, you need to also install what is called a .NET 4.5.2 targeting pack (also referred to as development pack in some places):

If you do not install the targeting pack and try to build against an older version of .NET with the wrong build tools, as was my case, then MSBuild 2015 tries to compensate by building the only way it knows how: By following the rules of .NET 4.6 (which should be backwards-compatible to 4.5.2 anyway) and throwing in a .NET DLL (mscorlib.dll) in the build folder.

In most cases, this would have still worked fine, except my code made use of String.Format() which suffered a very subtle breaking change between 4.5.2 and 4.6.

Philip Atz
  • 886
  • 1
  • 10
  • 26