MSBuild

This section documents MSBuild 18.9, the .NET SDK 10.0.402 (with its dotnet CLI) and NuGet 7.9, as published in the MSBuild, .NET and NuGet documentation on learn.microsoft.com, which is the reference these pages are written and verified against. Material about .NET 11 / NuGet 8.0 is still in preview and is always flagged as such — never presented as baseline.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The C# Reference bibliography lists the reference material consulted while preparing these pages.

MSBuild is the build engine of .NET: it reads XML project files, evaluates their properties and items, and runs targets made of tasks. Everything the .NET SDK does at build time — restore, compile, copy, pack, publish — is MSBuild logic shipped in .props and .targets files, and the same engine builds C++ and other Visual Studio project types. It is open source (dotnet/msbuild, MIT licence) and ships in three places: inside Visual Studio and the Build Tools for Visual Studio (msbuild.exe, .NET Framework, Windows), and inside every .NET SDK (dotnet msbuild, .NET, all platforms). This group documents MSBuild 18.9.15, the version in .NET SDK 10.0.402; Visual Studio 2026 18.11.1 carries 18.11, and the .NET 11 release candidates carry 18.12 (preview). The introduction to MSBuild in the C# Reference is Build and Tooling — MSBuild.

Three ways to run it

Command What it is

msbuild.exe

The .NET Framework MSBuild installed with Visual Studio or the Build Tools (Windows only). What Visual Studio itself uses; can load tasks built for .NET Framework and, since Visual Studio 2026 / .NET 10, tasks built for .NET through the .NET task host. Not run here.

dotnet msbuild

The .NET MSBuild inside the selected SDK. The CLI adds -maxcpucount, minimal verbosity and the Terminal Logger defaults (visible in the "Full command line" of an error), but it does not restore unless asked (-restore).

dotnet build, dotnet pack, dotnet test, …

The CLI’s front ends: they call the same in-process MSBuild with added defaults (-restore, -maxcpucount, the Terminal Logger, a summary). dotnet build is equivalent to dotnet msbuild -restore.

A five-line project with one target is a complete MSBuild project — no SDK, no compiler:

<Project>
  <PropertyGroup>
    <Ledger>Ledgerline</Ledger>
  </PropertyGroup>
  <Target Name="Hello">
    <Message Importance="high" Text="Hello from $(Ledger), built by MSBuild $(MSBuildVersion) on $(OS)." />
  </Target>
</Project>
dotnet msbuild hello.proj -t:Hello -nologo -v:m
dotnet msbuild -version
  Hello from Ledgerline, built by MSBuild 18.9.15 on Unix.
18.9.15.50611

The difference between dotnet msbuild and dotnet build shows on a fresh clone of the Ledgerline library, which has never been restored:

cd src/Ledgerline
dotnet msbuild -tl:off -v:m             # no restore: fails for each target framework
dotnet msbuild -restore -tl:off -v:m    # what dotnet build does
<sdk>/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(266,5): error NETSDK1004: Assets file '~/ledgerline/src/Ledgerline/obj/project.assets.json' not found. Run a NuGet package restore to generate this file. [~/ledgerline/src/Ledgerline/Ledgerline.csproj::TargetFramework=net8.0]
…
  Restored ~/ledgerline/src/Ledgerline/Ledgerline.csproj (in 281 ms).
  Ledgerline -> ~/ledgerline/src/Ledgerline/bin/Debug/netstandard2.0/Ledgerline.dll
  Ledgerline -> ~/ledgerline/src/Ledgerline/bin/Debug/net8.0/Ledgerline.dll
  Ledgerline -> ~/ledgerline/src/Ledgerline/bin/Debug/net10.0/Ledgerline.dll

Versions

MSBuild Visual Studio .NET SDK Notes

15.x

2017

.NET Core 1.x—​2.x

SDK-style projects

16.x

2019

.NET Core 3.x, .NET 5

17.0

2022 17.0

.NET 6

64-bit msbuild.exe

17.8

2022 17.8

.NET 8 (8.0.1xx)

Terminal Logger opt-in

17.12

2022 17.12

.NET 9 (9.0.1xx)

Terminal Logger default, BuildCheck

18.0

2026 18.0

.NET 10 (10.0.1xx)

.NET task host

18.9

 — 

10.0.4xx (10.0.402)

this section’s baseline

18.11

2026 18.11

 — 

latest stable release (GitHub v18.11.0)

18.12 (preview)

 — 

.NET 11 RC 2 (11.0.100-rc.2)

preview

dotnet msbuild -version (or msbuild -version) prints the version in use; $(MSBuildVersion) holds it inside a project. The full history is on Versions and Release History.

Release history at a glance

MSBuild has no "what’s new" page after 17.0; later changes are in the GitHub releases (whose tags were listed with git ls-remote on 2026-10-23), in the .NET SDK what’s-new pages and in the version notes inside individual MSBuild pages, which are what this table cites. Rows marked re-verify were not checked against a release note.

Release Change

15.0 (Visual Studio 2017)

SDK-style projects and the Sdk attribute; Directory.Build.props/.targets (re-verify)

15.8

RoslynCodeTaskFactory (cross-platform inline tasks) (re-verify)

16.x (Visual Studio 2019)

static graph builds (-graph, -isolate); -interactive — the documentation does not name the minor version (re-verify)

17.0 (Visual Studio 2022)

64-bit msbuild.exe by default; -warnNotAsError; smaller, richer binary logs; GetType() no longer allowed in property functions

17.8 (.NET 8)

Terminal Logger (-tl) opt-in; -getProperty, -getItem, -getTargetResult

17.12 (.NET 9)

Terminal Logger on by default for interactive dotnet builds; BuildCheck (-check, experimental); .slnx solutions build

17.13

.slnx found automatically when no project or solution is named

18.0 (Visual Studio 2026, .NET 10)

.NET task host: tasks built for .NET run in msbuild.exe and Visual Studio

18.6

-mt / -multiThreaded and IMultiThreadableTask (in-process multithreaded builds)

18.9

this section’s baseline (in SDK 10.0.4xx)

.NET 11 (preview, MSBuild 18.12)

MSBuild Server on by default for dotnet commands; change waves 17.10, 17.12, 17.14 and 18.3 removed