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

mar*_*ark 6 msbuild visual-studio visual-studio-2019

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

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
Run Code Online (Sandbox Code Playgroud)

这就是它发生的原因:

  1. 我们的项目都包含以下import语句: <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. 该文件夹$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)确实存在,请参见下文。

$(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:\>
Run Code Online (Sandbox Code Playgroud)

因此,VS 2019 实际上加载了Microsoft.VisualStudioVersion.v15.Common.props. 里面是什么?观察:

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:\>
Run Code Online (Sandbox Code Playgroud)

因此,在年底VSToolsPathC:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Microsoft\VisualStudio\v15.0这显然是错误的,因为没有这样的目录存在。存在的是 v16.0。

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

我错过了什么?

Lan*_*SFT 6

我们的项目都包含以下导入声明:<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props" Condition="'$(VSToolsPath)' == ''" />

我猜问题的根本原因是您将声明放在VSToolsPathproperty的定义之上。

在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>
Run Code Online (Sandbox Code Playgroud)

我假设您可以将语句添加到 xx.csproj 文件的顶部或上面的某个位置

<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

更新1:

关于导入元素的信息请参见此文档导入的项目按照导入的顺序进行检查。

更新2:

来自mark的提示,我在 msbuild 中发布了一个问题。链接