Как проверить для директив компилятора условие MSBuild в файле .csproj?

Я совершенно новичок в функциях и условиях в файлах .csproj, поэтому приветствуем любую помощь.

Что я хочу сделать, это проверить конкретную директиву компилятора в текущей конфигурации. Пример может выглядеть примерно так:

<Choose>
    <When Condition= [current configuration has CONST-1 compiler constant defined] >
        ...
    </When>
    <When Condition= [current configuration has CONST-2 compiler constant defined] >
        ...
    </When>
</Choose>

Я не знаю, возможно ли это или нет. Если есть лучший способ сделать то, что я прошу, дайте мне знать об этом. В любом случае, я хочу проверить условие независимое конфигурации.

ИЗМЕНИТЬ

То, что я действительно хочу, - это значение, которое я могу легко редактировать, предпочтительно в Visual Studio, и я также могу проверить, не имеет значения, что такое configuraiton. Я думал о константах компилятора, потому что вы можете легко изменить их в свойствах проекта в VS.

Ответ 1

Константы компилятора устанавливаются в свойство "DefineConstants", поэтому вы должны просто оценить это свойство. Ваш оператор Choose должен пройти после PropertyGroups, которые определяют константы или внутри цели.

<Choose>
    <When Condition="$(DefineConstants.Contains(CONST-1))">
        ...
    </When>
    <When Condition="$(DefineConstants.Contains(CONST-2))">
        ...
    </When>
</Choose>

Ответ 2

Если вы используете MSBuild 4 или выше, я предлагаю использовать регулярное выражение вместо String.Contains(). Причина этого заключается в том, что даже несмотря на то, что String.Contains() обычно работает хорошо, есть некоторые проблемы, которые могут возникнуть в проблемах.

Например:

Рассмотрим случай, когда вы используете в своем коде директивы CONST-1 и CONST-12. Однако вы решили определить только директиву CONST-12 для текущей сборки.
Теперь Condition="$(DefineConstants.Contains('CONST-1'))" оценивается как True, хотя CONST-1 не определен.

Решение с RegularExpressions.RegEx:

<When Condition="$([System.Text.RegularExpressions.Regex]::IsMatch($(DefineConstants), '^(.*;)*CONST-1(;.*)*$'))">
...
</When>

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

Ответ 3

Чтобы добавить к другим ответам, размещенным здесь, другой способ, которым вы можете это сделать, - обернуть свойство DefineConstants точкой с запятой, чтобы гарантировать, что "CONST-1;" будет содержаться в DefineConstants тогда и только тогда, когда определена константа CONST-1. Без точек с запятой у вас может быть CONST-100 или UNCONST-1, но не CONST-1, как переменная, и она будет оцениваться как true.

<PropertyGroup>
    <DefineConstants2>;$(DefineConstants);</DefineConstants2>
    <Foo Condition="'$(DefineConstants2.Contains(`;CONST-1;`))'">It worked</Foo>
    <Bar>$(Foo)</Bar> <!--It worked-->
</PropertyGroup>