无法使用 VS 2019 构建 Web 应用程序

Unable to build web applications with VS 2019

我安装了 VS 2019 Pro 并尝试编译我们的解决方案只是为了得到这个:

error MSB4226: The imported project "C:\Program Files (x86)\Microsoft
 Visual Studio19\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 Studio19\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

这就是它发生的原因:

  1. 我们的项目都包含以下导入语句:<Import Project="$(MSBuildExtensionsPath)$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props" Condition="'$(VSToolsPath)' == ''" />
  2. MSBuildExtensionsPath = C:\Program Files (x86)\Microsoft Visual Studio19\Professional\MSBuild
  3. MSBuildToolsVersion = Current
  4. 文件夹 $(MSBuildExtensionsPath)$(MSBuildToolsVersion) 确实存在,见下文。

$(MSBuildExtensionsPath)$(MSBuildToolsVersion):

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


    Directory: C:\Program Files (x86)\Microsoft Visual Studio19\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:\>

所以,VS 2019 实际加载 Microsoft.VisualStudioVersion.v15.Common.props。里面是什么?观察:

C:\> cat "C:\Program Files (x86)\Microsoft Visual Studio19\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:\>

所以,最后VSToolsPathC:\Program Files (x86)\Microsoft Visual Studio19\Professional\MSBuild\Microsoft\VisualStudio\v15.0,这显然是错误的,因为不存在这样的目录。存在的是 v16.0.

无论如何,这一切的根本原因似乎是 c:\Program Files (x86)\Microsoft Visual Studio19\Professional\MSBuild 向全世界传达了 MSBuild 15 是要使用的版本,而不是 MSBuild 16。

我错过了什么?

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

我想这个问题的根本原因是你把语句放在 VSToolsPath 属性.

的定义之上

在 VS2019 中创建一个简单的 asp.net web 应用程序(.net 框架),其结构如下所示:

<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>

我假设您可以将语句添加到 xx.csproj 文件的顶部或

文件上方的某处
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

如果是这样,因为现在 $(VSToolsPath) 还没有定义。它的值为空,然后构建系统将在您的语句中执行 Import 元素以导入 $(MSBuildExtensionsPath)$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props 文件,这将导致 VisualStudioVersion 属性 被设置为 15.0 而不是 16.0.

并且由于它从 Microsoft.VisualStudioVersion.v15.Common.props 导入属性,VSToolsPath 现在被设置为 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0,这将导致您得到的最终错误,因为 VSToolsPath 的路径部分=20=] 文件是 $(VSToolsPath)。参见:

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

因此,如果您将语句添加到 $(VSToolsPath) 的第一个定义之上,例如 位置 1,您将收到此错误。如果您在 $(VSToolsPath) 定义下方和 Import of Microsoft.WebApplication.targets 上方添加语句,如 位置 2,一切正常。

更新 1:

关于 Import 元素的信息参见 this document导入的项目按照导入的顺序进行检查。

更新2:

来自 mark 的提示,我 post msbuild 中的一个问题。 The link.

对我来说,以下方法有效。

在csproj文件中,

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

替换为

<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" />