propriedades MSBuild

Propriedades são pares nome-valor que podem ser usados para configurar compilações. Propriedades são úteis para passar valores para tarefas, avaliar condições e armazenar os valores que serão referenciados em todo o arquivo de projeto.

Definir e referenciar propriedades em um arquivo de projeto

As propriedades são declaradas com a criação de um elemento que tem o nome da propriedade como um filho de um elemento PropertyGroup. Por exemplo, o XML a seguir cria uma propriedade chamada BuildDir que tem um valor de Build.

<PropertyGroup>
    <BuildDir>Build</BuildDir>
</PropertyGroup>

Os nomes de propriedade válidos começam com uma letra maiúscula ou minúscula ou sublinhado (_); os caracteres subsequentes válidos incluem caracteres alfanuméricos (letras ou dígitos), sublinhado e hífen (-).

Em todo o arquivo de projeto, as propriedades são referenciadas usando a sintaxe $(<PropertyName>). Por exemplo, a propriedade no exemplo anterior é referenciada usando $(BuildDir).

Os valores de propriedade podem ser alterados redefinindo a propriedade. A propriedade BuildDir pode receber um novo valor usando este XML:

<PropertyGroup>
    <BuildDir>Alternate</BuildDir>
</PropertyGroup>

Todas as propriedades são avaliadas na ordem em que aparecem no arquivo de projeto. O novo valor de BuildDir deve ser declarado depois que o valor antigo for atribuído.

Propriedades reservadas

O MSBuild reserva alguns nomes de propriedade para armazenar informações sobre o arquivo de projeto e os binários do MSBuild. Essas propriedades são referenciadas com a notação $ como qualquer outra propriedade. Por exemplo, $(MSBuildProjectFile) retorna o nome de arquivo completo do arquivo de projeto, incluindo a extensão de nome de arquivo.

Para saber mais, confira Como referenciar o nome ou o local do arquivo de projeto e Propriedades reservadas e conhecidas do MSBuild.

Propriedades internas do MSBuild

As propriedades definidas em arquivos de importação padrão que começam com um sublinhado (_) são privadas para o MSBuild e não devem ser lidas, redefinidas ou substituídas no código do usuário.

Propriedades de ambiente

Você pode referenciar variáveis de ambiente em arquivos de projeto da mesma maneira que as propriedades reservadas. Por exemplo, para usar a variável de ambiente PATH em seu arquivo de projeto, use $(Path). Se o projeto contiver uma definição de propriedade que tem o mesmo nome que uma propriedade de ambiente, a propriedade no projeto substituirá o valor da variável de ambiente.

Cada projeto do MSBuild tem um bloco de ambiente isolado: apenas observa, lê e grava em seu próprio bloco. O MSBuild somente lê as variáveis de ambiente quando ele inicializa a coleção de propriedades, antes de o arquivo de projeto ser avaliado ou criado. Depois disso, as propriedades de ambiente são estáticas, ou seja, cada ferramenta gerada começa com os mesmos nomes e valores.

Para obter o valor atual de variáveis de ambiente em uma ferramenta gerada, use as Funções de propriedade System.Environment.GetEnvironmentVariable. O método preferido, entretanto, é usar o parâmetro de tarefa EnvironmentVariables. As propriedades de ambiente definidas nesta matriz de cadeia de caracteres podem ser passadas para a ferramenta gerada sem afetar as variáveis de ambiente do sistema.

Dica

Nem todas as variáveis de ambiente são lidas para se tornarem propriedades iniciais. Qualquer variável de ambiente cujo nome não seja um nome de propriedade do MSBuild válido, como "386", será ignorada.

Para saber mais, confira Como usar variáveis de ambiente em um build.

Propriedades de Registro

Leia valores de registro do sistema usando a sintaxe a seguir, em que Hive é o hive do Registro (por exemplo, HKEY_LOCAL_MACHINE), MyKey é o nome da chave, MySubKey é o nome da subchave e Value é o valor da subchave.

$(registry:Hive\MyKey\MySubKey@Value)

Para obter o valor da subchave padrão, omita o Value.

$(registry:Hive\MyKey\MySubKey)

Esse Registro pode ser usado para inicializar uma propriedade de build. Por exemplo, para criar uma propriedade de build que representa a home page do navegador da Web do Visual Studio, use este código:

<PropertyGroup>
  <VisualStudioWebBrowserHomePage>
    $(registry:HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0\WebBrowser@HomePage)
  </VisualStudioWebBrowserHomePage>
<PropertyGroup>

Aviso

Na versão do SDK do .NET do MSBuild (dotnet build), não há suporte para propriedades do Registro.

Criar propriedades durante a execução

As propriedades posicionadas fora dos elementos Target são valores atribuídos durante a fase de avaliação de um build. Durante a fase de execução subsequente, as propriedades podem ser criadas ou modificadas das seguintes maneiras:

  • Uma propriedade pode ser emitida por qualquer tarefa. Para emitir uma propriedade, o elemento Task deve ter um elemento filho Output que tem um atributo PropertyName.

  • Uma propriedade pode ser emitida pela tarefa CreateProperty. Esse uso é preterido.

  • Os elementos Target podem conter elementos PropertyGroup que podem conter declarações de propriedade.

Propriedades globais

O MSBuild permite a definição de propriedades na linha de comando com o uso da opção -property (ou -p). Esses valores de propriedades globais substituem os valores de propriedade que são definidos no arquivo de projeto. Isso inclui propriedades de ambiente, mas não inclui propriedades reservadas, que não podem ser alteradas.

O exemplo a seguir define a propriedade Configuration global como DEBUG.

msbuild.exe MyProj.proj -p:Configuration=DEBUG

As propriedades globais também podem ser definidas ou modificadas para projetos filho em um build de vários projetos usando o atributo Properties da tarefa do MSBuild. As propriedades globais também são encaminhadas para projetos filho, a menos que o atributo RemoveProperties da tarefa MSBuild seja usado para especificar a lista de propriedades que não devem ser encaminhadas. Para saber mais, confira Tarefa do MSBuild.

Propriedades locais

As propriedades locais podem ser redefinidas em um projeto. As propriedades globais não podem. Quando uma propriedade local é definida da linha de comando com a opção -p, a configuração no arquivo de projeto tem precedência sobre a linha de comando.

Especifique uma propriedade local usando o atributo TreatAsLocalProperty em uma marca de projeto.

O código a seguir especifica que duas propriedades são locais:

<Project Sdk="Microsoft.Net.Sdk" TreatAsLocalProperty="Prop1;Prop2">

As propriedades locais não são encaminhadas para projetos filho em uma compilação de vários projetos. Se você fornecer um valor na linha de comando com a opção -p, os projetos filho receberão o valor da propriedade global em vez do valor local alterado no projeto pai, mas o projeto filho (ou qualquer uma de suas importações) também poderá alterá-lo com seu próprio TreatAsLocalProperty.

Exemplo com propriedades locais

O exemplo de código a seguir demonstra o efeito de TreatAsLocalProperty:

<!-- test1.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <PropertyGroup>
        <TreatedAsLocalProp>LocalOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Target Name="Go">
        <MSBuild Projects="$(MSBuildThisFileDirectory)\test2.proj" Targets="Go2" Properties="Inner=true" />
    </Target>

    <Target Name="Go2" BeforeTargets="Go">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>
<!-- test2.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <Target Name="Go2">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>

Suponha que você crie uma linha de comando test1.proj e dê a TreatedAsLocalProperty o valor global GlobalOverrideValue:

dotnet msbuild .\test1.proj -p:TreatedAsLocalProp=GlobalOverrideValue

A saída é da seguinte maneira:

test1.proj(11,9): warning : TreatedAsLocalProp(test): LocalOverrideValue
test2.proj(3,9): warning : TreatedAsLocalProp(test2): GlobalOverrideValue

O projeto filho herda o valor global, mas o projeto pai usa a propriedade definida localmente.

Propriedades e importações locais

Quando o atributo TreatAsLocalProperty é usado no projeto importado, a ordem é importante ao considerar qual valor a propriedade obtém.

O exemplo de código a seguir mostra o efeito de TreatAsLocalProperty em um projeto importado:

<!-- importer.proj -->
<Project>
    <PropertyGroup>
        <TreatedAsLocalProp>FirstOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Import Project="import.props" />

    <PropertyGroup>
        <TreatedAsLocalProp Condition=" '$(TrySecondOverride)' == 'true' ">SecondOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Target Name="Go">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>
<!-- import.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <PropertyGroup>
        <TreatedAsLocalProp>ImportOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <!-- Here, TreatedAsLocalProp has the value "ImportOverrideValue"-->
</Project>

Suponha que você crie importer.proj e defina um valor global para TreatedAsLocalProp, conforme o seguinte:

dotnet msbuild .\importer.proj -p:TreatedAsLocalProp=GlobalOverrideValue

A saída é:

importer.proj(9,9): warning : TreatedAsLocalProp(importer.proj): GlobalOverrideValue

Agora suponha que você crie com a propriedade TrySecondOverride para true:

dotnet msbuild .\importer.proj -p:TreatedAsLocalProp=GlobalOverrideValue -p:TrySecondOverride=true

A saída é:

importer.proj(13,9): warning : TreatedAsLocalProp(importer.proj): SecondOverrideValue

O exemplo mostra que a propriedade é tratada como local após o projeto importado em que o atributo TreatAsLocalProperty foi usado, não apenas dentro do arquivo importado. O valor da propriedade é afetado pelo valor de substituição global, mas somente antes do projeto importado em que TreatAsLocalProperty é usado.

Para obter mais informações, confira Elemento Project (MSBuild) e Como criar os mesmos arquivos de origem com opções diferentes.

Funções de propriedade

A partir do .NET Framework versão 4, você pode usar funções de propriedade para avaliar seus scripts do MSBuild. Você pode ler a hora do sistema, comparar cadeias de caracteres, combinar expressões regulares e executar outras ações no script de build sem usar as tarefas do MSBuild.

Você pode usar métodos de cadeia de caracteres (instância) para operar qualquer valor da propriedade e pode chamar os métodos estáticos de muitas classes de sistema. Por exemplo, você pode definir uma propriedade de build com a data de hoje da seguinte maneira.

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

Para obter mais informações e uma lista de funções de propriedade, confira Funções de propriedade.

Armazenar o XML em propriedades

As propriedades podem conter XML arbitrário, que pode ajudar a passar valores para tarefas ou exibir informações de log. O exemplo a seguir mostra a propriedade ConfigTemplate, que tem um valor que contém o XML e outras referências de propriedade. O MSBuild substitui as referências de propriedade usando seus respectivos valores de propriedade. Os valores de propriedade são atribuídos na ordem em que aparecem. Portanto, nesse exemplo, $(MySupportedVersion), $(MyRequiredVersion) e $(MySafeMode) já devem ter sido definidos.

<PropertyGroup>
    <ConfigTemplate>
        <Configuration>
            <Startup>
                <SupportedRuntime
                    ImageVersion="$(MySupportedVersion)"
                    Version="$(MySupportedVersion)"/>
                <RequiredRuntime
                    ImageVersion="$(MyRequiredVersion)"
                    Version="$(MyRequiredVersion)"
                    SafeMode="$(MySafeMode)"/>
            </Startup>
        </Configuration>
    </ConfigTemplate>
</PropertyGroup>