Условие MsBuild для нового ("sdk-style") или старого формата проекта - PullRequest
0 голосов
/ 19 сентября 2018

Я хочу написать msbuild-файл «include» (.props), который должен быть импортирован как в новые («sdk-style») проекты, так и в старые.

Есть лиспособ выяснить, в какой тип проекта импортируется файл .props, чтобы я мог использовать его в условиях?Например,

<PropertyGroup Condition="'$(ProjectType)'=='sdk'">
   <SomeProperty>SomeValue</SomeProperty>
</PropertyGroup>

Ответы [ 4 ]

0 голосов
/ 29 ноября 2018

Я столкнулся с такой же потребностью в моем проекте.Сначала я решил использовать решение @wexman, но обнаружил, что эта переменная не является надежной.Я рассмотрел подход к открытию файла csproj и использованию регулярных выражений для поиска атрибута sdk, но он показался мне слишком хрупким - особенно учитывая, что sdk можно указывать либо в элементе, либо в атрибуте.Наконец, я создал сборку с включенным бинарным ведением журнала (опция /bl) и отправился на поиски различных файлов, которые импортируются при сборке проекта в стиле SDK.

Я обнаружил свойство UsingMicrosoftNETSdk, для которого установлено значение true в файле props, который автоматически импортирует Microsoft.Common.props при использовании проекта в стиле SDK.Этот автоматический импорт (который приводит к автоматическому импорту Directory.Build.props, по-видимому, является одной из наиболее важных определяющих характеристик проектов в стиле SDK, а имя свойства делает его похожим на нечто более вероятное.

Таким образом, в итоге мое решение должно было иметь:

Condition="'$(UsingMicrosoftNETSdk)' == 'true'"

(или его обратное) в качестве надежного способа определить, какой тип проекта используется.

0 голосов
/ 28 сентября 2018

Кажется, я нашел рабочее решение.Я проверяю свойство $ (_ PlatformWithoutConfigurationInference), объявленное в Microsoft.NET.Sdk.Props.Если он не пустой, я буду иметь дело с проектом в стиле SDK, если он пустой, это устаревший проект:

<Project>

  <PropertyGroup>
    <ProjectStyle Condition="'$(_PlatformWithoutConfigurationInference)'!=''">sdk</ProjectStyle>
    <ProjectStyle Condition="'$(_PlatformWithoutConfigurationInference)'==''">legacy</ProjectStyle>
  </PropertyGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Message Importance="High" Text="$(MsBuildProjectName) is a $(ProjectStyle) style project" />
  </Target>

</Project>
0 голосов
/ 13 ноября 2018

Хотя проверка значений свойств (или их отсутствие) заключается в том, как почти все выполняется в MSBuild, иногда существуют другие способы.

Как узнать, является ли текущий проект MSBuild SDKпроект?

Другими словами:

  • с данным файлом XML ...
  • , полный путь которого находится в скважине MSBuildProjectFullPath -известное свойство ...
  • и первый тег которого Project ...
  • имеет ли указанный тег атрибут Sdk?

Благодаря функциям свойства MSBuild вы можете сделать следующее:

  • использовать [System.IO.File]::ReadAllText для чтения содержимого файла проекта в виде строки;
  • , а затем использовать[System.Text.RegularExpressions.Regex]::IsMatch для проверки тега Project с атрибутом Sdk.
<PropertyGroup>
  <_ProjectContents>$([System.IO.File]::ReadAllText(`$(MSBuildProjectFullPath)`))</_ProjectContents>
  <_SdkRegex>(?s-i)(^|\s|&gt;)&lt;Project\s(([^&gt;]*?)\s)?Sdk(\s*?)=(\s*?)"</_SdkRegex>
  <_IsSdkProject>$([System.Text.RegularExpressions.Regex]::IsMatch(`$(_ProjectContents)`, `$(_SdkRegex)`))</_IsSdkProject>
</PropertyGroup>

Или, если вы предпочитаете однострочное:

<PropertyGroup>
  <_IsSdkProject>$([System.Text.RegularExpressions.Regex]::IsMatch(`$([System.IO.File]::ReadAllText(`$(MSBuildProjectFullPath)`))`, `(?s-i)(^|\s|&gt;)&lt;Project\s(([^&gt;]*?)\s)?Sdk(\s*?)=(\s*?)"`))</_IsSdkProject>
</PropertyGroup>

ТогдаВы можете использовать значение _IsSdkProject, которое будет True ИЛИ False в Condition, например:

<PropertyGroup Condition="'$(_IsSdkProject)'=='True'">
  <SomeProperty>SomeValue</SomeProperty>
</PropertyGroup>

Регулярное выражение объяснено

ВВыше регулярного выражения символы < и > были заменены на объекты XML (&lt; и &gt; соответственно).Исходное регулярное выражение выглядит следующим образом:

(?s-i)(^|\s|>)<Project\s(([^>]*?)\s)?Sdk(\s*?)=(\s*?)"

Что означает:

  • В однострочный, чувствительный к регистру режим ...
  • Либо в начале файла, либо после символа пробела, либо после символа > ...
  • найдите буквенную строку <Project ...
  • затем символ пробела ...
  • затем, произвольно, любое число любого символа, кроме >, и еще один символ пробела ...
  • затем буквенная строка Sdk ...
  • , затем, по выбору, любое количество символов пробела ...
  • , затем символ = ...
  • , затем, по выбору, любойколичество пробелов ...
  • затем символ "

Лучшее объяснение, вместе с онлайн-тестером, куда вы можете вставить содержимое файлов вашего проекта и проверитьв режиме реального времени - на regex101.com .Сайт был создан для регулярных выражений Javascript, которые не ведут себя точно , как в .NET, но в любом случае это полезно.

0 голосов
/ 21 сентября 2018

Условие MsBuild для нового («sdk-style») в сравнении со старым форматом проекта

Нет прямого решения для этого вопроса.Поскольку в MSBuild / Visual Studio нет такого свойства ProjectType.

Я бы хотел обойти это здесь, вы можете проверить, работает ли оно у вас.Как мы знаем, в старом формате проекта обычно будет файл AssemblyInfo.cs, которого нет в новом формате проекта "sdk-style".Таким образом, мы могли бы использовать Condition="Exists('$(ProjectDir)\Properties\AssemblyInfo.cs')", чтобы узнать, в какой тип проекта импортируется файл .props:

Содержимое моего тестового файла .props:

 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="Exists('$(ProjectDir)\Properties\AssemblyInfo.cs')">
    <SomeProperty>SomeValue1</SomeProperty>
  </PropertyGroup>

  <PropertyGroup Condition="!Exists('$(ProjectDir)\Properties\AssemblyInfo.cs')">
    <SomeProperty>SomeValue2</SomeProperty>
  </PropertyGroup>

  <Target Name="Test" AfterTargets="AfterBuild">
    <Message Text="$(SomeProperty)"></Message>
  </Target>
</Project>

Надеждаэто помогает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...