11

For an old project I support, I've been performing some modernization. That has included various things: bumping the .NET Framework up to 4.6, and other upgrades. One of the things we have some leeway to do is make syntactic upgrades, provided we don't change business logic.

We've also recently installed Visual Studio 2015, and the latest and greatest ReSharper, which revealed that "String Interpolation" is now something we can do in our code. For those who don't know, string interpolation is syntactic sugar over string.Format calls as below:

// Normal, pre-C#6 formatting:
var foo = string.Format("Some string {0}", bar);

// C#6 String Interpolation
var foo = $"Some string {bar}";

This is really useful because it makes the messages a lot easier to read, and usually by taking up fewer characters.

...Yet, TeamCity seems to disagree. When I pushed the code up in a commit, I got the following error:

Directory\SomeFile.cs: error CS1056: Unexpected character '$' [C:\ProjectDirectory\Project.Core\Project.Core.csproj]

On the surface, it seems like a pre-C#6 builder of some sort is being hit, because this is a new feature to C#6.

Here's what I have observed that is why I theorize that this is what's going on:

  1. The build configuration is pointing to C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe This gives me pause, because presumably .NET 4.6 is installed on our build agent.

  2. Upon trying to directly install .NET 4.6 from the Microsoft installer, though, it fails because .NET 4.6 is already installed on the bulid agent.

  3. Our build configuration's compile step is giving me pause as well. The first two lines that note the version of the Build Engine and framework respectively are [exec] Microsoft (R) Build Engine version 4.6.1055.0 [exec] [Microsoft .NET Framework, version 4.0.30319.42000] The build engine is apparently v4.6, but the .NET framework is 4.0!? Am I reading that right?

  4. Lastly, one of the final lines of the build log: [NAnt output] External Program Failed: C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe (return code was 1) That is not 4.6...is it?

Question: Twofold. This first question might be stupid, but am I actually compiling against .NET 4.6? Secondly, in what way can I get the String Interpolation syntax in C#6 to actually build, if I am pointing to .NET 4.6?

I'm clearly missing something about all of this, I'm not sure A) how many things I'm missing, or B) what exactly I should do about them.

Andrew Gray
  • 3,756
  • 3
  • 39
  • 75

1 Answers1

29

I feel vindicated; the funny path/version was in fact indicative of the true problem: the MSBuild.exe that was being ran was not the one installed by VS2015.

As I read from here, the version of MSBuild.exe that is found in C:\Windows\Microsoft.NET\Framework\v4.0.30319 is actually a pre-C#6 version; for some reason, installing Visual Studio 2015 does not alter that installation!

Instead you should point your MSBuild.exe call to the copy stored at C:\Program Files (x86)\MSBuild\14.0\Bin to be compiling against the latest C# version, as installed by VS2015.

Andrew Gray
  • 3,756
  • 3
  • 39
  • 75
  • 4
    For completeness, you don't actually need to install VS2015 on each build agent; it can become pretty cumbersome if you have several. Just install [Microsoft Build Tools 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48159) and TeamCity should pick this up as satisfied in the Agent Requirements. Then you can select Build Tool 2015 in your MSBuild step (if that's what you're using). – SteveChapman Jan 05 '16 at 21:48
  • We actually use a NAnt script, with a path to the builder we want to use...but, that's a good suggestion! Thanks. – Andrew Gray Jan 05 '16 at 21:50
  • Update for people running VS 2019 - always check your paths! VS 2019 installs to a different path than the one I posted roughly five years ago now (!!!). – Andrew Gray Apr 22 '20 at 16:09