Поиск и использование версии MSBuild

Чтобы гарантировать, что автоматические сборки вашего приложения совпадают со сборками, выполняемыми в Visual Studio или MSBuild.exe, возможно, потребуется загрузить ту же версию сборок MSBuild, которая была установлена с конкретной версией Visual Studio, и использовать те же SDK, которые доступны в этой версии Visual Studio. Кроме того, при создании приложения сборки, которое будет выполняться на компьютерах с различными установленными версиями MSBuild, .NET и Visual Studio, можно также найти и использовать согласованную версию MSBuild. Майкрософт. Build.Locator API упрощает этот процесс.

Используйте Майкрософт. Build.Locator

Пакет Майкрософт.Build.Locator актуален в ситуациях, когда ваше приложение работает на клиентских машинах, виртуальных машинах или в контейнерах, где установлен Visual Studio, либо в средах, где установлены только средства сборки Visual Studio или лишь SDK .NET, например, когда сборки запрашиваются с помощью командной строки dotnet build. В любом случае приложение должно найти нужную версию MSBuild. Эта версия MSBuild может быть версией, которая соответствует Visual Studio, MSBuild.exeили dotnet build или определенной согласованной версии независимо от различных конфигураций компьютеров в средах, где может использоваться ваше приложение.

Предупреждение

Пакет Майкрософт.Build.Locator содержит сборки для платформ .NET Framework и .NET Core (также применимо к .NET 5 и более поздним версиям). В приложении .NET Framework используется версия Майкрософт.Build.Locator для .NET Framework, а в приложении .NET Core используется версия Майкрософт.Build.Locator для .NET Core. Однако версия .NET Core может находить только экземпляры MSBuild, созданные с помощью .NET Core, и MSBuild, используемый dotnet.exe в установках пакета SDK .NET, а не в установках Visual Studio или Visual Studio Build Tools. Версия Майкрософт.Build.Locator для .NET Framework может видеть только установки Visual Studio, установки Visual Studio Build Tools, а не установки .NET SDK. Поэтому может потребоваться создать средство в двух разных конфигурациях целевой платформы для того, чтобы использовать оба варианта.

Если вы распространяете Майкрософт.Build.Locator.dll с приложением, вам не нужно распространять другие сборки MSBuild.

Использование API указателя требует нескольких изменений в проекте, описанных ниже. Пример изменений, необходимых для обновления проекта, можно увидеть в коммитах, сделанных в примерном проекте в репозитории MSBuildLocator.

Изменение ссылок MSBuild

Чтобы убедиться, что MSBuild загружается из центрального расположения, не следует распространять его сборки вместе с приложением.

Механизм изменения вашего проекта, чтобы избежать загрузки MSBuild из центрального места, зависит от того, как вы ссылаетесь на MSBuild.

Использование пакетов NuGet (предпочтительный)

Эти инструкции предполагают, что вы используете ссылки NuGet в стиле PackageReference.

Измените файлы вашего проекта, чтобы они ссылались на библиотеки MSBuild из их пакетов NuGet. Укажите ExcludeAssets=runtime, чтобы сообщить NuGet, что сборки необходимы только во время сборки и не должны быть скопированы в выходной каталог.

Основная и дополнительная версия пакетов MSBuild должна быть меньше или равна минимальной версии Visual Studio, которую вы хотите поддерживать. Например, если вы хотите поддерживать Visual Studio 2017 и более поздние версии, используйте версию пакета 15.1.548.

Например, этот XML-код можно использовать:

<ItemGroup>
  <PackageReference Include="Microsoft.Build" Version="15.1.548" ExcludeAssets="runtime" />
  <PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.548" ExcludeAssets="runtime" />
</ItemGroup>

Используйте библиотеки расширения

Если вы не можете использовать пакеты NuGet, можно ссылаться на сборки MSBuild, распределенные с Visual Studio. Если вы прямо ссылаетесь на MSBuild, убедитесь, что он не копируется в выходной каталог, установив значение Copy Local на False. В файле проекта этот параметр похож на следующий код:

    <Reference Include="Microsoft.Build, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <Private>False</Private>
    </Reference>

Заметка

Если вы обновляетесь с версии MSBuild до 15, MSBuild требует перенаправления привязок для определенных сборок (Майкрософт.Build сборки), но если вы ссылаетесь на пакет Майкрософт.Build.Locator, убедитесь, что приложение автоматически использует необходимые перенаправления привязок к версии 15.1.0.0. Перенаправления привязки к этой версии поддерживают MSBuild 15.x, 16.x, 17.x и 18.x.

Убедитесь, что выходные данные чисты

Создайте проект и проверьте выходной каталог, чтобы убедиться, что он не содержит сборок Майкрософт.Build.*.dll, отличных от Майкрософт.Build.Locator.dll, добавленных на следующем шаге.

Добавьте ссылку на пакет для Майкрософт. Build.Locator

Добавьте ссылку на пакет NuGet для Майкрософт. Build.Locator.

    <PackageReference Include="Microsoft.Build.Locator">
      <Version>1.1.2</Version>
    </PackageReference>

Не указывайте ExcludeAssets=runtime для пакета Майкрософт.Build.Locator.

Регистрация экземпляра перед вызовом MSBuild

При создании приложения сборки для общего использования вы не знаете, какие версии Visual Studio, .NET и MSBuild могут быть установлены на компьютере, на котором выполняется приложение. Цель MSBuildLocator — найти соответствующую установку MSBuild для использования на компьютерах с различными средами установки. MSBuildLocator позволяет вам определить логику для выбора версии MSBuild, которую следует использовать. Как разработчик приложения, вы должны самостоятельно определить, какая версия MSBuild необходима или приемлема для вашего приложения. В противном случае, предоставьте пользователям возможность указать нужную версию, а также включите логику для преобразования их выбора в соответствующие вызовы к API MSBuildLocator.

Самый простой способ добавить вызов в API указателя — добавить вызов MSBuildLocator.RegisterInstance в код запуска приложения. Один из примеров — выбрать последнюю версию, как показано здесь, но ваше приложение может иметь собственные требования.

Вы не можете ссылаться на типы MSBuild (из пространства имен Майкрософт.Build) в методе, который вызывает MSBuildLocator. Например, нельзя использовать следующий код:

void ThisWillFail()
{
    // Register the most recent version of MSBuild
    RegisterInstance(MSBuildLocator.QueryVisualStudioInstances().OrderByDescending(
       instance => instance.Version).First());
    Project p = new Project(SomePath); // Could be any MSBuild type
    // Code that uses the MSBuild type
}

Вместо этого напишите следующий код:

void MethodThatDoesNotDirectlyCallMSBuild()
{
    var instance = ... // select which of the installed instances to use
    
    // Register a specific instance of MSBuild
    MSBuildLocator.RegisterInstance(instance);
    MethodThatCallsMSBuild();
}

void MethodThatCallsMSBuild()
{
    Project p = new Project(SomePath);
    // Code that uses the MSBuild type
}

Чтобы указать экземпляр MSBuild, можно выбрать результат MSBuildLocator.QueryVisualStudioInstances для передачи MSBuildLocator.RegisterInstance с использованием необходимой пользовательской логики.

Сведения об API MSBuild см. в справочнике по API MSBuild: