Visual Studio 2019 MSBuild Error when Building .sln

Problem Description

After completely cleaning up all Visual Studio installations and reinstalling Visual Studio 2019 Version 16.8.7, I was no longer able to build solutions (*.sln) using MSBuild from the command line (“Developer Command Prompt for VS 2019”). I got an error when executing the following commands:

md test
cd test
dotnet new sln
msbuild test.sln
Microsoft (R) Build Engine version 16.8.3+39993bd9d for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

Building the projects in this solution one at a time. To enable parallel build, please add the "-m" switch.
Build started 13.03.2021 09:20:25.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\SolutionFile\ImportAfter\Microsoft.NET.Sdk.Solution.targets(14,3): error MSB4019: The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.Common.targets" was not found. Confirm that the expression in the Import declaration "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.Common.targets" is correct, and that the file exists on disk.

Build FAILED.

  C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\SolutionFile\ImportAfter\Microsoft.NET.Sdk.Solution.targets(14,3): error MSB4019: The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2019
\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.Common.targets" was not found. Confirm that the expression in the Import declaration "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.Common.targets" is correct, and that the file exists on disk.

    0 Warning(s)
    1 Error(s)

Time Elapsed 00:00:00.08

Solution

The error could be fixed by deleting the following file:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\SolutionFile\ImportAfter\Microsoft.NET.Sdk.Solution.targets

Background Information

Not sure where this file was coming from and if it is needed for other purposes. Just for reference, here is the content of this file:

<!--
***********************************************************************************************
Microsoft.NET.Sdk.Solution.targets

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) .NET Foundation. All rights reserved.
***********************************************************************************************
-->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Import Project="$(MSBuildSDKsPath)\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.Common.targets" />
  
  <!--
  ============================================================
                              _CheckForSolutionLevelRuntimeIdentifier

    Ensure that a runtime identifier is not specified at the solution level
  ============================================================
   -->
  <Target Name="_CheckForSolutionLevelRuntimeIdentifier"
          BeforeTargets="Build"
          Condition="'$(RuntimeIdentifier)' != ''">

    <NETSdkError ResourceName="CannotHaveSolutionLevelRuntimeIdentifier" />

  </Target>

</Project>

It’s important to note that no MSBuildSDKsPath environment variable was set, which is as it should be. For some reason, MSBuild determined it to be C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Sdks. This folder exists, but it doesn’t contain the expected Microsoft.NET.Sdk subfolder. This subfolder only resides in the various C:\Program Files\dotnet\sdk\{version}\Sdks directories.

Obviously MSBuild includes all files from C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\SolutionFile\ImportAfter (no matter how they are named) and tries to process them when a solution (*.sln) is built. For some reason, the malicious Microsoft.NET.Sdk.Solution.targets file creeped into the file system and broke the build.