MSBuild (propriétés)

Les propriétés sont des paires nom-valeur qui peuvent être utilisées pour configurer des générations. Elles sont utiles pour transmettre des valeurs aux tâches, évaluer des conditions et stocker les valeurs qui seront référencées dans tout le fichier projet.

Définir et référencer des propriétés dans un fichier projet

Les propriétés sont déclarées en créant un élément portant le nom de la propriété comme enfant d’un élément PropertyGroup. Par exemple, le code XML suivant crée une propriété nommée BuildDir pourvue de la valeur Build.

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

Les noms de propriétés valides commencent par une lettre majuscule ou minuscule ou un trait de soulignement (_). Les caractères suivants valides incluent des caractères alphanumériques (lettres ou chiffres), un trait de soulignement et un trait d’union (-).

Les propriétés sont référencées dans tout le fichier projet à l’aide de la syntaxe $(<PropertyName>). Par exemple, la propriété indiquée dans l’exemple précédent est référencée à l’aide de $(BuildDir).

La valeur d’une propriété peut être modifiée en redéfinissant la propriété. Une nouvelle valeur peut être octroyée à la propriété BuildDir en utilisant ce code XML :

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

Les propriétés sont évaluées dans l’ordre dans lequel elles apparaissent dans le fichier projet. La nouvelle valeur de la propriété BuildDir doit être déclarée après que l’ancienne valeur a été affectée.

Propriétés réservées

MSBuild réserve certains noms de propriété pour stocker des informations sur le fichier projet et les binaires de MSBuild. Ces propriétés sont référencées avec la notation $ comme toute autre propriété. Par exemple, $(MSBuildProjectFile) retourne le nom de fichier complet du fichier projet, y compris l’extension de nom de fichier.

Pour plus d’informations, consultez Guide pratique pour référencer le nom ou l’emplacement du fichier projet et Propriétés réservées et connues de MSBuild.

Propriétés internes de MSBuild

Les propriétés définies dans les fichiers d’importation standard qui commencent par un trait de soulignement (_) sont réservées à MSBuild et ne doivent pas être lues, réinitialisées ou remplacées dans le code utilisateur.

Propriétés d’environnement

Vous pouvez référencer des variables d’environnement des fichiers projet de la même façon que les propriétés réservées. Par exemple, pour utiliser la variable d’environnement PATH dans votre fichier projet, utilisez $(Path). Si le projet contient une définition de propriété qui porte le même nom qu’une propriété d’environnement, la propriété du projet remplace la valeur de la variable d’environnement.

Chaque projet MSBuild dispose d’un bloc environnement isolé : il voit seulement les lectures et écritures de son propre bloc. MSBuild lit uniquement les variables d’environnement lors de l’initialisation de la collection de propriétés, avant que le fichier projet ne soit évalué ou généré. À l’issue de cette opération, les propriétés d’environnement sont statiques. Autrement dit, chaque outil généré commence par les mêmes noms et valeurs.

Pour obtenir la valeur actuelle des variables d’environnement à partir d’un outil généré, utilisez les fonctions de propriétés System.Environment.GetEnvironmentVariable. La méthode préférée est cependant d’utiliser le paramètre de tâche EnvironmentVariables. Les propriétés d’environnement définies dans ce tableau de chaînes peuvent être transmises à l’outil généré sans affecter les variables d’environnement système.

Conseil

Toutes les variables d’environnement ne sont pas lues pour devenir des propriétés initiales. Une variable d’environnement dont le nom n’est pas un nom de propriété MSBuild valide, par exemple « 386 », est ignoré.

Pour plus d’informations, consultez Guide pratique pour utiliser des variables d’environnement dans une build.

Propriétés de Registre

Vous pouvez lire les valeurs du Registre système à l’aide de la syntaxe suivante, où Hive est la ruche du Registre (par exemple, HKEY_LOCAL_MACHINE), MyKey le nom de la clé, MySubKey le nom de la sous-clé, et Value la valeur de la sous-clé.

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

Pour obtenir la valeur de la sous-clé par défaut, omettez la Value.

$(registry:Hive\MyKey\MySubKey)

Cette valeur du Registre peut être utilisée pour initialiser une propriété de génération. Par exemple, pour créer une propriété de génération qui représente la page d’accueil Visual Studio Web Browser, utilisez ce code :

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

Avertissement

Dans la version du SDK .NET de MSBuild (dotnet build), les propriétés de Registre ne sont pas prises en charge.

Créer des propriétés pendant l’exécution

Des valeurs sont attribuées aux propriétés situées en dehors des éléments Target pendant la phase d’évaluation d’une génération. Pendant la phase d’exécution suivante, des propriétés peuvent être créées ou modifiées en procédant comme suit :

  • Une propriété peut être émise par une tâche quelconque. Pour émettre une propriété, l’élément Task doit posséder un élément Output enfant pourvu d’un attribut PropertyName.

  • Une propriété peut être émise par la tâche CreateProperty. Cette utilisation est dépréciée.

  • Les éléments Target peuvent contenir des éléments PropertyGroup, qui peuvent comporter des déclarations de propriété.

Propriétés globales

MSBuild vous permet de définir des propriétés sur la ligne de commande à l’aide du commutateur -property (ou -p). Les valeurs de ces propriétés globales remplacent les valeurs de propriétés qui sont définies dans le fichier projet. Cela inclut les propriétés d’environnement, mais pas les propriétés réservées, qui ne peuvent pas être modifiées.

L’exemple suivant définit la propriété globale Configuration sur DEBUG.

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

Les propriétés globales peuvent également être définies ou modifiées pour les projets enfants d’une génération multiprojet à l’aide de l’attribut Properties de la tâche MSBuild. Des propriétés globales sont également transférées aux projets enfants, sauf si l’attribut RemoveProperties de la tâche MSBuild est utilisé pour spécifier la liste des propriétés à ne pas transférer. Pour plus d’informations, consultez l’article Tâche MSBuild.

Propriétés locales

Les propriétés locales peuvent être réinitialisées dans un projet. Cela n’est pas le cas pour les propriétés globales. Lorsqu’une propriété locale est définie à partir de la ligne de commande avec l’option -p, le paramètre dans le fichier projet est prioritaire sur la ligne de commande.

Vous spécifiez une propriété locale à l’aide de l’attribut TreatAsLocalProperty dans une balise de projet.

Le code suivant spécifie que deux propriétés sont locales :

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

Les propriétés locales ne sont pas transférées aux projets enfants dans un build à plusieurs projets. Si vous fournissez une valeur sur la ligne de commande avec l’option -p, les projets enfants reçoivent la valeur de la propriété globale au lieu de la valeur locale modifiée dans le projet parent, mais le projet enfant (ou l’une de ses importations) peut également la modifier avec son propre TreatAsLocalProperty.

Exemple avec des propriétés locales

L’exemple de code suivant montre l’impact 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>

Supposons que vous générez la ligne de commande test1.proj et que vous attribuez à TreatedAsLocalProperty la valeur globale GlobalOverrideValue :

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

La sortie se présente comme suit :

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

Le projet enfant hérite de la valeur globale, mais le projet parent utilise la propriété définie localement.

Propriétés et importations locales

Lorsque l’attribut TreatAsLocalProperty est utilisé sur un projet importé, l’ordre est important pour déterminer la valeur que la propriété obtient.

L’exemple de code suivant montre l’impact de TreatAsLocalProperty sur un projet importé :

<!-- 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>

Supposons que vous générez importer.proj et définissez une valeur globale pour TreatedAsLocalProp comme suit :

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

La sortie est la suivante :

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

Supposons maintenant que vous générez avec la propriété TrySecondOverride pour true :

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

La sortie est la suivante :

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

L’exemple montre que la propriété est traitée comme locale après le projet importé où l’attribut TreatAsLocalProperty a été utilisé, pas seulement dans le fichier importé. La valeur de la propriété est affectée par la valeur de remplacement globale, mais uniquement avant le projet importé où TreatAsLocalProperty est utilisé.

Pour plus d’informations, consultez Project, élément (MSBuild) et Guide pratique pour générer les mêmes fichiers sources avec des options différentes.

Fonctions de propriétés

Depuis .NET Framework version 4, vous pouvez utiliser les fonctions de propriétés pour évaluer vos scripts MSBuild. Vous pouvez lire l’heure système, comparer des chaînes, établir des correspondances avec des expressions régulières et effectuer d’autres actions dans votre script de génération sans utiliser de tâches MSBuild.

Vous pouvez utiliser des méthodes chaîne (instance) sur toute valeur de propriété, et vous pouvez appeler les méthodes statiques de nombreuses classes système. Par exemple, vous pouvez définir une propriété de génération à la date du jour comme suit.

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

Pour plus d’informations et pour obtenir la liste des fonctions de propriétés, consultez Fonctions de propriétés.

Stocker du code XML dans les propriétés

Les propriétés peuvent contenir un code XML arbitraire, ce qui peut aider à transmettre des valeurs aux tâches ou à afficher les informations de journalisation. L’exemple suivant présente la propriété ConfigTemplate, qui est pourvue d’une valeur qui contient le code XML et d’autres références de propriété. MSBuild remplace les références de propriété par leurs valeurs de propriété respectives. Les valeurs de propriété sont attribuées dans l’ordre dans lequel elles apparaissent. Par conséquent, dans cet exemple, les propriétés $(MySupportedVersion), $(MyRequiredVersion) et $(MySafeMode) doivent déjà avoir été définies.

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