Funções de propriedade

As funções de propriedade são chamadas para métodos do .NET que aparecem nas definições de propriedade do MSBuild. Ao contrário das tarefas, as funções de propriedade podem ser usadas fora dos destinos. As funções de propriedade são avaliadas sempre que as propriedades ou itens são expandidos. Portanto, para propriedades e itens fora de qualquer destino, as funções de propriedade são avaliadas antes de qualquer execução de destino. Para grupos de propriedades e grupos de itens dentro de destinos, as funções de propriedade são avaliadas quando o destino é avaliado.

Sem o uso de tarefas MSBuild, você pode ler a hora do sistema, comparar cadeias de caracteres, combinar expressões regulares e executar outras ações no script de compilação. O MSBuild tentará converter a cadeia de caracteres em número e número em cadeia de caracteres, além de fazer outras conversões, conforme necessário.

Valores de cadeia de caracteres retornados de funções de propriedade tem caracteres especiais de escape. Se você quiser que o valor seja tratado como se fosse colocado diretamente no arquivo do projeto, use $([MSBuild]::Unescape()) para desfazer o escape dos caracteres especiais.

Sintaxe da função de propriedade

Três tipos de funções de propriedade estão listados abaixo. Cada função possui uma sintaxe diferente:

  • Funções de propriedade de cadeia de caracteres (instância)
  • Funções de propriedade estática
  • Funções de propriedade MSBuild

Funções de propriedade de cadeia de caracteres

Todos os valores de propriedade de compilação são apenas valores de cadeia de caracteres. Você pode usar métodos de cadeia (instância) para operar em qualquer valor de propriedade. Por exemplo, você pode extrair o nome da unidade (os três primeiros caracteres) de uma propriedade de compilação que representa um caminho completo usando este código:

$(ProjectOutputFolder.Substring(0,3))

Funções de propriedade estática

No seu script de compilação, você pode acessar propriedades e métodos estáticos de muitas classes de sistema. Para obter o valor de uma propriedade estática, use a sintaxe a seguir, em que Class é o nome da classe do sistema e Property é o nome da propriedade.

$([Class]::Property)

Por exemplo, você pode usar o seguinte código para definir uma propriedade de compilação para a data e hora atual.

<Today>$([System.DateTime]::Now)</Today>

Para chamar um método estático, use a seguinte sintaxe, em que Class é o nome da classe de sistema, Method é o nome do método e (Parameters) é a lista de parâmetros para o método:

$([Class]::Method(Parameters))

Por exemplo, para definir uma propriedade de compilação para um novo GUID, você pode usar este script:

<NewGuid>$([System.Guid]::NewGuid())</NewGuid>

Em funções de propriedade estática, você pode usar qualquer propriedade ou método estático público destas classes de sistema:

Você pode usar também as seguintes propriedades e métodos estáticos:

Funções da propriedade System.OperatingSystem

As funções da propriedade System.OperatingSystem retornam informações sobre o sistema operacional no qual o MSBuild está em execução. Por exemplo, se o projeto for direcionado ao Linux e você compilá-lo no macOS, as funções da propriedade retornarão informações sobre o macOS.

No MSBuild em execução no .NET (dotnet build), todos os métodos estáticos da classe System.OperatingSystem serão chamados como funções da propriedade estática.

No MSBuild em execução no .NET Framework (MSBuild.exe), somente os seguintes métodos estáticos de System.OperatingSystem serão chamados como funções da propriedade estática. O MSBuild os implementa internamente, porque System.OperatingSystem não os define no .NET Framework. Os métodos para sistemas operacionais para os quais não há SDK do .NET, como System.OperatingSystem::IsTvOS, não podem ser chamados.

O exemplo a seguir mostra o uso dessas funções da propriedade.

<IsWindows>$([System.OperatingSystem]::IsWindows())</IsWindows>

Chamar métodos de instância em propriedades estáticas

Se você acessar uma propriedade estática que retorna uma instância de objeto, poderá invocar métodos de instância desse objeto. Para invocar um método de instância, use a seguinte sintaxe, em que Class é o nome de classe de sistema, Property é o nome da propriedade, Method é o nome do método e (Parameters) é a lista de parâmetros para o método:

$([Class]::Property.Method(Parameters))

O nome da classe deve ser totalmente qualificado com o namespace.

Por exemplo, você pode usar o seguinte código para definir uma propriedade de compilação para a data atual.

<Today>$([System.DateTime]::Now.ToString('yyyy.MM.dd'))</Today>

Funções de propriedade MSBuild

Vários métodos estáticos em sua compilação podem ser acessados para fornecer aritmética, lógica de bit a bit e suporte a caracteres de escape. Você pode acessar esses métodos usando a seguinte sintaxe, em que Method é o nome do método e (Parameters) é a lista de parâmetros para o método.

$([MSBuild]::Method(Parameters))

Por exemplo, para adicionar duas propriedades com valores numéricos, use o código a seguir.

$([MSBuild]::Add($(NumberOne), $(NumberTwo)))

Aqui está uma lista de funções da propriedade MSBuild:

Assinatura de função Descrição
double Add(double a, double b) Adicionar dois duplos.
long Add(long a, long b) Adicionar dois longos.
double Subtract(double a, double b) Subtrair dois duplos.
long Subtract(long a, long b) Subtrair dois longos.
double Multiply(double a, double b) Multiplicar dois duplos.
long Multiply(long a, long b) Multiplicar dois longos.
double Divide(double a, double b) Dividir dois duplos.
long Divide(long a, long b) Dividir dois longos.
double Modulo(double a, double b) Modular dois duplos.
long Modulo(long a, long b) Modular dois longos.
string Escape(string unescaped) Escapar a cadeia de caracteres de acordo com a regras de escape do MSBuild.
string Unescape(string escaped) Deixar sem escape a cadeia de caracteres de acordo com a regras de escape do MSBuild.
int BitwiseOr(int first, int second) Realizar um OR bit a bit no primeiro e segundo (first | second).
int BitwiseAnd(int first, int second) Realizar um bit a bit AND no primeiro e segundo (primeiro e segundo).
int BitwiseXor(int first, int second) Realizar um bit a bit XOR no primeiro e segundo (primeiro ^ segundo).
int BitwiseNot(int first) Realizar um bit a bit NOT (~primeiro).
bool IsOsPlatform(string platformString) Especifique se a plataforma do sistema operacional atual é platformString. platformString deve ser um membro do OSPlatform.
bool IsOSUnixLike() True se o sistema operacional atual for um sistema Unix.
string NormalizePath(params string[] path) Obtém o caminho completo canonizado do caminho fornecido e garante que ele contém os caracteres do separador de diretório corretos para o sistema operacional atual.
string NormalizeDirectory(params string[] path) Obtém o caminho completo canonizado do diretório fornecido e garante que ele contém os caracteres do separador de diretório corretos para o sistema operacional atual, enquanto garante que tem uma barra à direita.
string EnsureTrailingSlash(string path) Se o caminho especificado não tiver uma barra à direita, adicione uma. Se o caminho for uma cadeia de caracteres vazia, não a modifique.
string GetPathOfFileAbove(string file, string startingDirectory) Pesquisa e retorna o caminho completo para um arquivo na estrutura de diretórios em e acima do local do arquivo de build atual ou com base no startingDirectory, se especificado.
string GetDirectoryNameOfFileAbove(string startingDirectory, string fileName) Localizar e retornar o diretório de um arquivo no diretório especificado ou em um local na estrutura de diretório acima desse diretório.
string MakeRelative(string basePath, string path) Torna o path relativo a basePath. basePath deve ser um diretório absoluto. Se path não puder ser tornado relativo, ele será retornado de forma textual. Similar a Uri.MakeRelativeUri.
string ValueOrDefault(string conditionValue, string defaultValue) Retorna a cadeia de caracteres no parâmetro defaultValue somente se o parâmetro conditionValue estiver vazio, caso contrário, retorna o valor conditionValue.
string ConvertToBase64(string toEncode) Retorna a cadeia de caracteres depois de converter todos os bytes em base 64 (caracteres alfanuméricos mais + e /), terminando em um ou dois =.
string ConvertFromBase64(string toDecode) Retorna a cadeia de caracteres depois de converter de base 64 (caracteres alfanuméricos mais + e /), terminando em um ou dois =.

Funções de propriedade aninhadas

Você pode combinar funções de propriedade para formar funções mais complexas, como mostra o seguinte exemplo:

$([MSBuild]::BitwiseAnd(32, $([System.IO.File]::GetAttributes(tempFile))))

Este exemplo retorna o valor do FileAttributes.Bit do Archive (32 ou 0) do arquivo fornecido pelo caminho tempFile. Observe que os valores de dados enumerados não podem aparecer por nome em alguns contextos. No exemplo anterior, o valor numérico (32) deve ser usado. Em outros casos, dependendo das expectativas do método chamado, o valor dos dados de enumeração deve ser usado. No exemplo a seguir, o valor de enumeração RegexOptions.O ECMAScript deve ser usado porque um valor numérico não pode ser convertido como este método espera.

<PropertyGroup>
    <GitVersionHeightWithOffset>$([System.Text.RegularExpressions.Regex]::Replace("$(PrereleaseVersion)", "^.*?(\d+)$", "$1", "System.Text.RegularExpressions.RegexOptions.ECMAScript"))</GitVersionHeightWithOffset>
</PropertyGroup>

Metadados também podem aparecer em funções de propriedade aninhadas. Para obter mais informações, consulte Envio em lote.

MSBuild DoesTaskHostExist

A função de propriedade DoesTaskHostExist no MSBuild retorna se um host de tarefas está instalado atualmente para os valores de runtime e arquitetura especificados.

Essa função de propriedade tem a seguinte sintaxe:

$([MSBuild]::DoesTaskHostExist(string theRuntime, string theArchitecture))

EnsureTrailingSlash do MSBuild

A função de propriedade EnsureTrailingSlash no MSBuild adicionará uma barra à direita se não houver.

Essa função de propriedade tem a seguinte sintaxe:

$([MSBuild]::EnsureTrailingSlash('$(PathProperty)'))

MSBuild GetDirectoryNameOfFileAbove

A função de propriedade GetDirectoryNameOfFileAbove do MSBuild pesquisa nos níveis acima se há um diretório que contém o arquivo especificado, começando no diretório especificado e inclusive nele. Ela retorna o caminho completo do diretório mais próximo que contém o arquivo se ele for encontrado, caso contrário, uma cadeia de caracteres vazia.

Essa função de propriedade tem a seguinte sintaxe:

$([MSBuild]::GetDirectoryNameOfFileAbove(string startingDirectory, string fileName))

Este exemplo mostra como importar o arquivo EnlistmentInfo.props mais próximo dentro ou acima da pasta atual, somente se uma correspondência for encontrada:

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), EnlistmentInfo.props))' != '' " />

Observe que este exemplo pode ser escrito de maneira mais concisa usando a função GetPathOfFileAbove:

<Import Project="$([MSBuild]::GetPathOfFileAbove(EnlistmentInfo.props))" Condition=" '$([MSBuild]::GetPathOfFileAbove(EnlistmentInfo.props))' != '' " />

GetPathOfFileAbove do MSBuild

A função de propriedade GetPathOfFileAbove do MSBuild pesquisa nos níveis acima se há um diretório que contém o arquivo especificado, começando no diretório especificado e inclusive nele. Ela retorna o caminho completo do arquivo correspondente mais próximo se for encontrado, caso contrário, uma cadeia de caracteres vazia.

Essa função de propriedade tem a seguinte sintaxe:

$([MSBuild]::GetPathOfFileAbove(string file, [string startingDirectory]))

em que file é o nome do arquivo a ser pesquisado e startingDirectory é um diretório opcional para iniciar a pesquisa. Por padrão, a pesquisa será iniciada no próprio diretório do arquivo atual.

Este exemplo mostra como importar um arquivo chamado dir.props dentro ou acima do diretório atual, somente se uma correspondência for encontrada:

<Import Project="$([MSBuild]::GetPathOfFileAbove(dir.props))" Condition=" '$([MSBuild]::GetPathOfFileAbove(dir.props))' != '' " />

que é funcionalmente equivalente a

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))' != '' " />

No entanto, às vezes, você precisa iniciar a pesquisa no diretório pai para evitar a correspondência com o arquivo atual. Este exemplo mostra como um arquivo Directory.Build.props pode importar o arquivo Directory.Build.props mais próximo em um nível estritamente mais alto da árvore, sem importar recursivamente a si mesmo:

<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

que é funcionalmente equivalente a

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove('$(MSBuildThisFileDirectory)../', 'Directory.Build.props'))/Directory.Build.props" />

MSBuild GetRegistryValue

A função da propriedade GetRegistryValue do MSBuild retorna o valor de uma chave de registro. Essa função usa dois argumentos, o nome da chave e o nome do valor, e retorna o valor do registro. Se você não especificar um nome de valor, o valor padrão será retornado.

Os exemplos a seguir mostram como a função é usada:

$([MSBuild]::GetRegistryValue(`HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\Debugger`, ``))                                  // default value
$([MSBuild]::GetRegistryValue(`HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\Debugger`, `SymbolCacheDir`))
$([MSBuild]::GetRegistryValue(`HKEY_LOCAL_MACHINE\SOFTWARE\(SampleName)`, `(SampleValue)`))             // parens in name and value

Aviso

Na versão do SDK do .NET do MSBuild (dotnet build), não há suporte para essa função.

MSBuild GetRegistryValueFromView

A função de propriedade GetRegistryValueFromView do MSBuild obtém os dados de registro do sistema, dados a chave do registro, o valor e uma ou mais exibições de registro solicitada. A chave e o valor são pesquisados em cada exibição do registo em ordem até serem encontrados.

A sintaxe para essa função de propriedade é:

[MSBuild]::GetRegistryValueFromView(string keyName, string valueName, object defaultValue, params object[] views)

O sistema operacional Windows de 64 bits mantém uma chave do Registro HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node que apresenta uma exibição do Registro HKEY_LOCAL_MACHINE\SOFTWARE para aplicativos de 32 bits.

Por padrão, um aplicativo de 32 bits em execução no WOW64 acessa a exibição do registro de 32 bits e um aplicativo de 64 bits acessa a exibição do registro de 64 bits.

As seguintes exibições de registro estão disponíveis:

Exibição do Registro Definição
RegistryView.Registry32 A exibição do registro do aplicativo de 32 bits.
RegistryView.Registry64 A exibição do registro do aplicativo de 64 bits.
RegistryView.Default A exibição do registro que corresponde ao processo em que o aplicativo está sendo executado.

A seguir, é mostrado um exemplo.

$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Silverlight\v3.0\ReferenceAssemblies', 'SLRuntimeInstallPath', null, RegistryView.Registry64, RegistryView.Registry32))

obtém os dados de SLRuntimeInstallPath da chave ReferenceAssemblies, procurando primeiro na exibição do registro de 64 bits e depois na exibição do registro de 32 bits.

Aviso

Na versão do SDK do .NET do MSBuild (dotnet build), não há suporte para essa função.

MSBuild MakeRelative

A função de propriedade MakeRelative do MSBuild retorna o caminho relativo do segundo caminho relativo ao primeiro caminho. Cada caminho pode ser um arquivo ou pasta.

Essa função de propriedade tem a seguinte sintaxe:

$([MSBuild]::MakeRelative($(FileOrFolderPath1), $(FileOrFolderPath2)))

O código a seguir mostra um exemplo dessa sintaxe.

<PropertyGroup>
    <Path1>c:\users\</Path1>
    <Path2>c:\users\username\</Path2>
</PropertyGroup>

<Target Name = "Go">
    <Message Text ="$([MSBuild]::MakeRelative($(Path1), $(Path2)))" />
    <Message Text ="$([MSBuild]::MakeRelative($(Path2), $(Path1)))" />
</Target>

<!--
Output:
   username\
   ..\
-->

MSBuild StableStringHash

A função de propriedade MSBuild StableStringHash aceita um argumento de cadeia de caracteres e retorna um código de hash que tem garantia para ser estável, o que significa que o mesmo código é sempre retornado para a mesma entrada de cadeia de caracteres. O hash retornado é o mesmo, independentemente de MSBuild ou dotnet build é usado, e é estável em toda a arquitetura de plataforma, ao contrário do método .NET GetHashCode. Não é garantido que seja estável em diferentes versões do MSBuild.

Essa função está disponível no MSBuild 16.9.0 ou posterior.

Os exemplos a seguir mostram como essa função é usada.

<Project>
   <PropertyGroup>
      <MyHash>$([MSBuild]::StableStringHash("test1"))</MyHash>
   </PropertyGroup>

   <Target Name="WriteHash" AfterTargets="Build">
      <Message Text="Hash: $(MyHash)"/>
   </Target>
</Project>

A partir da versão 17.10.0 do MSBuild, essa função aceita um segundo argumento, opcional, que solicita o algoritmo de hash a ser usado:

<Project>
   <PropertyGroup>
      <MyHash>$([MSBuild]::StableStringHash("test1", "Sha256"))</MyHash>
   </PropertyGroup>

   <Target Name="WriteHash" AfterTargets="Build">
      <Message Text="Hash: $(MyHash)"/>
   </Target>
</Project>

O segundo argumento não diferencia maiúsculas de minúsculas, e atualmente oferece suporte aos seguintes valores:

  • Herdado - Mantém o mesmo comportamento de chamar a função sem o segundo argumento. Retorna um inteiro de 32 bits assinado com propriedades semelhantes à string.GetHashCode.
  • Fnv1a32bit - Retorna um inteiro de 32 bits assinado que representa um hash Fowler-Noll-Vo da versão '1a' do hash da string fornecida.
  • Fnv1a64bit - Retorna um inteiro de 64 bits assinado que representa um hash Fowler-Noll-Vo da versão '1a' do hash da string fornecida.
  • Sha256 - Retorna uma string hexadecimal sem prefixo que representa um hash SHA256 da string fornecida.

MSBuild ValueOrDefault

A função de propriedade ValueOrDefault do MSBuild retorna o primeiro argumento, a menos que seja nulo ou esteja vazio. Se o primeiro argumento for nulo ou estiver vazio, a função retornará o segundo argumento.

Os exemplos a seguir mostram como essa função é usada.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <Value1>$([MSBuild]::ValueOrDefault('$(UndefinedValue)', 'a'))</Value1>
        <Value2>$([MSBuild]::ValueOrDefault('b', '$(Value1)'))</Value2>
    </PropertyGroup>

    <Target Name="MyTarget">
        <Message Text="Value1 = $(Value1)" />
        <Message Text="Value2 = $(Value2)" />
    </Target>
</Project>

<!--
Output:
  Value1 = a
  Value2 = b
-->

Funções TargetFramework e TargetPlatform do MSBuild

O MSBuild 16.7 e superior definem várias funções para lidar com as propriedades TargetFramework e TargetPlatform.

Assinatura de função Descrição
GetTargetFrameworkIdentifier(string targetFramework) Analisar o TargetFrameworkIdentifier do TargetFramework.
GetTargetFrameworkVersion(string targetFramework, int versionPartCount) Analisar o TargetFrameworkVersion do TargetFramework.
GetTargetPlatformIdentifier(string targetFramework) Analisar o TargetPlatformIdentifier do TargetFramework.
GetTargetPlatformVersion(string targetFramework, int versionPartCount) Analisar o TargetPlatformVersion do TargetFramework.
IsTargetFrameworkCompatible(string targetFrameworkTarget, string targetFrameworkCandidate) Retornará 'True' se a estrutura de destino candidata (segundo argumento) for compatível com a estrutura de destino indicada pelo primeiro argumento e false caso contrário.

O parâmetro versionPartCount de GetTargetFrameworkVersion e GetTargetPlatformVersion tem um valor padrão de 2.

O exemplo a seguir mostra como essas funções são usadas.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <Value1>$([MSBuild]::GetTargetFrameworkIdentifier('net5.0-windows7.0'))</Value1>
        <Value2>$([MSBuild]::GetTargetFrameworkVersion('net5.0-windows7.0'))</Value2>
        <Value3>$([MSBuild]::GetTargetPlatformIdentifier('net5.0-windows7.0'))</Value3>
        <Value4>$([MSBuild]::GetTargetPlatformVersion('net5.0-windows7.0'))</Value4>
        <Value5>$([MSBuild]::IsTargetFrameworkCompatible('net5.0-windows', 'net5.0'))</Value5>
        <Value6>$([MSBuild]::IsTargetFrameworkCompatible('net5.0', 'net6.0'))</Value6>
        <Value7>$([MSBuild]::IsTargetFrameworkCompatible('net5.0', 'net8.0'))</Value7>
    </PropertyGroup>

    <Target Name="MyTarget">
        <Message Text="Value1 = $(Value1)" />
        <Message Text="Value2 = $(Value2)" />
        <Message Text="Value3 = $(Value3)" />
        <Message Text="Value4 = $(Value4)" />
        <Message Text="Value5 = $(Value5)" />
        <Message Text="Value6 = $(Value6)" />
        <Message Text="Value7 = $(Value7)" />
    </Target>
</Project>
Value1 = .NETCoreApp
Value2 = 5.0
Value3 = windows
Value4 = 7.0
Value5 = True
Value6 = False
Value7 = False

Funções de comparação de versão do MSBuild

O MSBuild 16.5 e versões superiores definem várias funções para comparar cadeias de caracteres que representam versões.

Observação

Os operadores de comparação em condições podem comparar cadeias de caracteres que podem ser analisadas como System.Versionobjetos, mas a comparação pode produzir resultados inesperados. Prefira as funções de propriedade.

Assinatura de função Descrição
VersionEquals(string a, string b) Retorna true se as versões a e b forem equivalentes de acordo com as regras abaixo.
VersionGreaterThan(string a, string b) Retorna true se a versão a for maior que b de acordo com as regras abaixo.
VersionGreaterThanOrEquals(string a, string b) Retorna true se a versão a for maior ou igual a b de acordo com as regras abaixo.
VersionLessThan(string a, string b) Retorna true se a versão a for menor que b de acordo com as regras abaixo.
VersionLessThanOrEquals(string a, string b) Retorna true se a versão a for menor ou igual a b de acordo com as regras abaixo.
VersionNotEquals(string a, string b) Retorna false se as versões a e b forem equivalentes de acordo com as regras abaixo.

Nesses métodos, as versões são analisadas como System.Version, com as seguintes exceções:

  • O v ou V à esquerda é ignorado, o que permite a comparação com $(TargetFrameworkVersion).

  • Tudo, desde o primeiro "-" ou "+" até o final da cadeia de caracteres da versão, é ignorado. Isso permite passar versões semânticas (semver), embora a ordem não seja a mesma que a semver. Em vez disso, especificadores de pré-lançamento e metadados de build não têm nenhum peso de classificação. Isso pode ser útil, por exemplo, para ativar um recurso na >= x.y e fazer com que ele seja ativado na x.y.z-pre.

  • Partes não especificadas são iguais a partes de valor zero. (x == x.0 == x.0.0 == x.0.0.0).

  • O espaço em branco não é permitido em componentes inteiros.

  • Somente a versão principal é válida (3 é igual a 3.0.0.0)

  • + não é permitido como sinal positivo em componentes inteiros (é tratado como metadados semver e ignorado)

Dica

Comparações de propriedades TargetFramework geralmente devem usar IsTargetFrameworkCompatible em vez de extrair e comparar versões. Isso permite comparar TargetFrameworks que variam em TargetFrameworkIdentifier tanto quanto na versão.

Funções de condição do MSBuild

As funções Exists e HasTrailingSlash não são funções de propriedade. Elas estão disponíveis para uso com o atributo Condition. Confira Condições do MSBuild.