Microsoft.Build.Locator

repository·main·Indexed 42 days ago

https://github.com/microsoft/msbuildlocator

A tool for applications to locate and register MSBuild assemblies distributed with Visual Studio or the .NET SDK. It ensures applications can correctly load and evaluate complex MSBuild projects by providing access to the same SDKs and build logic used by MSBuild.exe, dotnet build, or Visual Studio.

Tokens
2K
Snippets
5
Records
8
Agent score
54%

What's inside MSBuild Locator

  1. What is Microsoft.Build.Locator for?

    main

    Microsoft.Build.Locator is used to correctly load MSBuild projects (such as .csproj, .vbproj, .fsproj, .sqlproj, and .ccproj) by locating a valid MSBuild installation on the host machine.

    While MSBuild can be provided via NuGet packages, loading complex projects requires access to the SDKs and build logic distributed with Visual Studio, Visual Studio extensions, or the .NET SDK. Using the Locator ensures your application uses the same MSBuild context as MSBuild.exe, dotnet build, or Visual Studio, providing access to the same bug fixes, features, and performance improvements.

  2. What is Microsoft.Build.Locator and when to use it

    main

    Microsoft.Build.Locator is a utility used to locate and register MSBuild assemblies distributed with Visual Studio or the .NET SDK.

    When to use it: You need this library when your application uses MSBuild's .NET APIs to evaluate or build projects. Simply having the MSBuild NuGet packages is often insufficient; you also need access to the SDKs and build logic installed on the host machine. Using MSBuildLocator ensures your application sees the same project environment as MSBuild.exe, dotnet build, or Visual Studio.

  3. How MSBuild.Locator searches for the .NET SDK

    main

    MSBuild.Locator identifies the locally installed SDK by probing environment variables and paths in a specific order of priority. Probing stops as soon as the first dotnet executable is found.

    The search priority is:

    1. DOTNET_ROOT
    2. The current process path (if MSBuild.Locator is called from dotnet.exe)
    3. DOTNET_HOST_PATH
    4. DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR
    5. PATH

    For detailed definitions of these variables, refer to the .NET Environment Variables documentation.

  4. Resolve MSBL001 by excluding MSBuild runtime assets

    main

    To resolve the MSBL001 error, add ExcludeAssets="runtime" and PrivateAssets="all" to all MSBuild-related PackageReference items in your project file.

    • ExcludeAssets="runtime": Ensures NuGet uses the packages for compilation only. At runtime, MSBuildLocator will load the assemblies from the registered Visual Studio or .NET SDK.
    • PrivateAssets="all": Prevents these package references from being passed transitively to downstream projects.

    If the error refers to a package you do not directly reference, it is a transitive reference. You must explicitly add a PackageReference for that specific package in your project file and apply the exclusions to resolve the error.

    <ItemGroup>
      <PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" PrivateAssets="all" />
      <PackageReference Include="Microsoft.Build.Framework" ExcludeAssets="runtime" PrivateAssets="all" />
      <PackageReference Include="Microsoft.Build.Utilities.Core" ExcludeAssets="runtime" PrivateAssets="all" />
      <!-- Add other MSBuild packages as needed -->
    </ItemGroup>
  5. Quick Start: Register MSBuild assemblies

    main

    To use MSBuild APIs (like Microsoft.Build.Evaluation.Project) in your application, you must first locate and register the MSBuild assemblies provided by Visual Studio or the .NET SDK.

    Critical Requirement: Because of how the Common Language Runtime (CLR) loads assemblies, you MUST call MSBuildLocator.RegisterDefaults() before any types from the MSBuild assemblies are used in your application. To prevent accidental premature loading, it is recommended to wrap MSBuild API calls in a separate method.

    using Microsoft.Build.Locator;
    using Microsoft.Build.Evaluation;
    
    // Register defaults before using any MSBuild types
    MSBuildLocator.RegisterDefaults();
    
    // Now you can safely use MSBuild APIs.
    // NOTE: due to the way that the CLR loads assemblies, you MUST
    //       register MSBuild through Locator before any types from 
    //       the MSBuild assemblies are used in your application.
    //       The safest way to ensure this is to put any MSBuild API
    //       access into a separate method.
    LoadProject();
    
    void LoadProject()
    {
      var project = new Project("MyProject.csproj");
      ...
    }
  6. Disable the MSBuild assembly copy check

    main

    If you have a specific requirement to distribute MSBuild assemblies directly with your application (which is generally not recommended and not supported by the MSBuild team), you can disable the MSBL001 check by setting the DisableMSBuildAssemblyCopyCheck property to true in your project file.

    Warning: Disabling this check may lead to issues with SDK resolution and build logic behavior.

    <PropertyGroup>
      <DisableMSBuildAssemblyCopyCheck>true</DisableMSBuildAssemblyCopyCheck>
    </PropertyGroup>
  7. Fix MSBL001: MSBuild runtime package referenced without asset exclusion

    main

    The MSBL001 error occurs when your project references MSBuild NuGet packages (e.g., Microsoft.Build, Microsoft.Build.Framework, Microsoft.Build.Utilities.Core) without excluding their runtime assets.

    When using Microsoft.Build.Locator, you want the locator to load MSBuild assemblies from an installed Visual Studio or .NET SDK instance. If the NuGet package's runtime assets are copied to your output directory, your application might load those instead of the registered installation, leading to:

    • Assembly version conflicts: The app loads local bin folder assemblies while MSBuildLocator tries to use a different installation.
    • Missing SDKs: Local assemblies lack the necessary SDKs, targets, and build logic.
    • Inconsistent behavior: Discrepancies between your app and dotnet build or Visual Studio.

    Note: Do not add ExcludeAssets or PrivateAssets to the Microsoft.Build.Locator package itself, as you need its runtime assets to function.

    <!-- Example of the error message -->
    > A PackageReference to the package '{PackageId}' at version '{Version}' is present in this project without ExcludeAssets="runtime" and PrivateAssets="all" set. This can cause errors at run-time due to MSBuild assembly-loading.
  8. Register a specific MSBuild instance

    main

    If you need more control than the default registration provides, you can query available Visual Studio instances and register a specific one. This allows you to target a particular version of MSBuild (for example, the latest version available on the machine).

    using Microsoft.Build.Locator;
    
    // Query available MSBuild instances
    var instances = MSBuildLocator.QueryVisualStudioInstances().ToArray();
    
    // Register a specific instance
    var instance = instances.OrderByDescending(i => i.Version).First();
    MSBuildLocator.RegisterInstance(instance);