Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to build web applications with VS 2019

I installed VS 2019 Pro and tried to compile our solution just to get this:

error MSB4226: The imported project "C:\Program Files (x86)\Microsoft
 Visual Studio\2019\Professional\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" was not found. Also, tried
 to find "WebApplications\Microsoft.WebApplication.targets" in the fallback search path(s) for $(VSToolsPath) - "C:\Program Files (x86)\MSBuild\Mi
crosoft\VisualStudio\v15.0" . These search paths are defined in "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\
Bin\MSBuild.exe.Config". Confirm that the path in the <Import> declaration is correct, and that the file exists on disk in one of the search paths

Here is why it happens:

  1. Our projects all include the following import statement: <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props" Condition="'$(VSToolsPath)' == ''" />
  2. MSBuildExtensionsPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild
  3. MSBuildToolsVersion = Current
  4. The folder $(MSBuildExtensionsPath)\$(MSBuildToolsVersion) indeed exists, see below.

$(MSBuildExtensionsPath)\$(MSBuildToolsVersion):

C:\> dir "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current"


    Directory: C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        6/13/2019   9:11 PM                Bin
d-----        5/27/2019   4:42 PM                Imports
d-----        5/27/2019   4:41 PM                Microsoft.Common.targets
d-----        5/27/2019   4:42 PM                SolutionFile
-a----        5/27/2019   4:38 PM          13606 Microsoft.Common.props
-a----        5/27/2019   4:38 PM            789 Microsoft.VisualStudioVersion.v15.Common.props
-a----        5/27/2019   4:38 PM           2029 THIRDPARTYNOTICES.txt


C:\>

So, VS 2019 actually loads Microsoft.VisualStudioVersion.v15.Common.props. And what is inside? Observe:

C:\> cat "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Microsoft.VisualStudioVersion.v15.Common.props"
<!--
***********************************************************************************************
Microsoft.VisualStudio.v15.Common.props

WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
          created a backup copy.  Incorrect changes to this file will make it
          impossible to load or build your projects from the command-line or the IDE.

Copyright (C) Microsoft Corporation. All rights reserved.
***********************************************************************************************
-->

<Project>

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

</Project>
C:\>

So, at the end VSToolsPath is C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Microsoft\VisualStudio\v15.0 which is obviously wrong, because no such directory exists. What does exist is v16.0.

Anyway, it seems the root cause for all of this is c:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild communicates to the world that MSBuild 15 is version to be used instead of MSBuild 16.

What am I missing?

like image 924
mark Avatar asked Sep 09 '19 15:09

mark


2 Answers

Our projects all include the following import statement: <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props" Condition="'$(VSToolsPath)' == ''" />

I guess the root cause of the issue is that you put the statement above the definition of VSToolsPath property.

Create a simple asp.net web application(.net framework) in VS2019 and its structure looks like this:

<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    ...
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    ...
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    ...
  </PropertyGroup>

  <ItemGroup>
    ...
  </ItemGroup>

  <!--Position 1-->
  <!--<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props" Condition="'$(VSToolsPath)' == ''" />--> <!--Position 1-->
  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <!--This is where the VSToolsPath is defined.-->
  </PropertyGroup>

  <!--Position 2-->
  <!--<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props" Condition="'$(VSToolsPath)' == ''" />--> <!--Position 2-->
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <!--This is where the error finally occurs.-->
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
  <ProjectExtensions>
    ...
  </ProjectExtensions>
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. ...-->
</Project>

I assume you may add the statement in the top of the xx.csproj file or somewhere above the

<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

If so, since now $(VSToolsPath) is not defined yet. Its value is empty, then the build system will execute the Import element in your statement to Import $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props file, which will then result in the VisualStudioVersion property be set 15.0 instead of 16.0.

And since it import properties from Microsoft.VisualStudioVersion.v15.Common.props, the VSToolsPath is now set as $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0, and this will cause the final error you get since the part of the path to Microsoft.WebApplication.targets file is $(VSToolsPath). See:

<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <!--This is where the error finally occurs.-->

So if you add your statement above the first definition of $(VSToolsPath) like position 1, you'll get this error. If you add your statement below the definition of $(VSToolsPath) and above the Import of Microsoft.WebApplication.targets like position 2, all works well.

Update1:

About the info of Import element see this document. imported projects are inspected in the order that they are imported.

Update2:

Hint from mark, I post an issue in msbuild. The link.

like image 149
LoLance Avatar answered Oct 11 '22 19:10

LoLance


For me, the following worked.

In the csproj file,

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

is replaced with

<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" />
like image 2
VivekDev Avatar answered Oct 11 '22 18:10

VivekDev