2

I'm using Visual Studio 2017 (ver15.6.6) with .NET Framework ver4.7.02558 (MSBuild ver15.5.x) aka latest updates at the time of this writing. When I create an ASP.NET Web Project using the default template the resulting .csproj file contains this snippet:

<PropertyGroup>
  <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
  <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
[...]
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />

As you can see Microsoft.WebApplication.targets is imported twice. I'm scratching my head over this block of the .csproj:

  • First of all the 2nd entry is disabled due to Condition="false" (am I missing something here?) So this begs the question what's the deal with this import statement in the first place?
  • Second of all the 2nd statement points to v10.0 instead of v15.0. Errrr woOt? Shouldn't it be v15.0?
  • Third of all this bit:

    < VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0< / VisualStudioVersion>
    

    should probably be:

    < VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0< /VisualStudioVersion>
    

For testing purposes I commented out the first statement and enabled the second one like so:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" Condition="true" />

This seems to work just fine both in my dev machine and the headless CI server we have. I'm mentioning this because if the default \v10.0\ is used then the build system breaks in a very esoteric manner down the road:

In our CI server the web-publish mechanism silently fails to spawn anything in the output folder and at the same time it produces no error whatsoever (gah!).

This is a known issue which seems to be affecting many users. Checkout the answer by rianjs here:

https://github.com/Microsoft/msbuild/issues/1901

He came to the same conclusion as I did. I can't fathom why the default template for VS17 doesn't have built in provisions to address such subtleties in the default build system as illustrated above.

All these default settings of the .csproj seem way off, completely misleading and constitute batteries for all sorts of weird, silent and hard-to-figure-out errors. Especially when it comes to CI servers.

In order to resolve these issues with the default templates do I need to update the templates of visual studio separately through an addon or something to get healthy templates for VS17? What's going on here?

XDS
  • 3,786
  • 2
  • 36
  • 56

1 Answers1

1

ASP.NET Web Project Template contains 2 entries for importing Microsoft.WebApplication.targets $VSToolsPath) vs $(MSBuildExtensionsPath32)

It is not easy to troubleshooting this issue, that because there are many reasons for this issue, server environment, Visual Studio extension, some nuget packages and so on. I would like provide some thoughts about this issue.

According to your description, if you commented out the first statement and enabled the second one, you can build the successfully on the build server. So it seems the variable of VSToolsPath not working in the first statement.

When we open the project file .csproj with notepad, we will see following imports:

  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
  </PropertyGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />

You can build successfully with <Import Project="...\v15.0\WebApplications\Microsoft.WebApplication.targets" Condition="true" /> but failed with default template, obviously, the value of $(VSToolsPath) is not correct or null in the first statement, and the value of $(VSToolsPath) depends on the value of $(VisualStudioVersion). The $(VisualStudioVersion) is defined in the file Microsoft.VisualStudioVersion.v15.Common.props:

  <PropertyGroup>
    <VisualStudioVersion>15.0</VisualStudioVersion>
    <VSToolsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
  </PropertyGroup>

</Project>

The location of that file: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0

So, if the first statement not imported correct,

first, please check if the file Microsoft.VisualStudioVersion.v15.Common.props exists on your build server

Second, check if you call the MSBuild from Visual Studio 2017: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin.

Third, check if you have install any other nuget in your project, for example, Microsoft.VSSDK.BuildTools, Visual Studio 2017 extension - VSToolsPath not working.

If all above not help you, a workaround is to create custom project template with statement:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" Condition="true" />

Hope this helps.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • I have done all those things and as I explained everything checks out. The question is not on that. The question is why is the default template broken in the first place for so many years across so many different versions of VS? It shouldn't be **that** hard to fix the template. – XDS Apr 26 '18 at 11:18
  • @xDisruptor, I see. You doubt that the default template is broken in the first place, but I tried to reproduce this with VS2017 or MSBuild but don't think I did. If the default is broken, you should get the error when you publish it from local VS. You can check if you still have this issue when you publish it with VS or MSBuild command line on your local. – Leo Liu Apr 27 '18 at 07:45