Présentation du fichier projet

par Jason Lee

Microsoft Build Engine fichiers projet (MSBuild) se trouvent au cœur du processus de génération et de déploiement. Cette rubrique commence par une vue d’ensemble conceptuelle de MSBuild et du fichier projet. Il décrit les composants clés que vous rencontrerez lorsque vous travaillez avec des fichiers projet, et il fonctionne à travers un exemple d’utilisation des fichiers projet pour déployer des applications réelles.

Ce que vous allez apprendre :

  • Comment MSBuild utilise les fichiers projet MSBuild pour générer des projets.
  • Comment MSBuild s’intègre aux technologies de déploiement, telles que l’outil de déploiement web Iis (Internet Information Services) (Web Deploy).
  • Comment comprendre les composants clés d’un fichier projet.
  • Comment utiliser des fichiers projet pour générer et déployer des applications complexes.

MSBuild et le fichier projet

Lorsque vous créez et générez des solutions dans Visual Studio, Visual Studio utilise MSBuild pour générer chaque projet dans votre solution. Chaque projet Visual Studio inclut un fichier projet MSBuild, avec une extension de fichier qui reflète le type de projet, par exemple un projet C# (.csproj), un projet Visual Basic.NET (.vbproj) ou un projet de base de données (.dbproj). Pour générer un projet, MSBuild doit traiter le fichier projet associé au projet. Le fichier projet est un document XML qui contient toutes les informations et instructions dont MSBuild a besoin pour générer votre projet, comme le contenu à inclure, les exigences de la plateforme, les informations de contrôle de version, les paramètres de serveur web ou de serveur de base de données et les tâches à effectuer.

Les fichiers projet MSBuild sont basés sur le schéma XML MSBuild et, par conséquent, le processus de génération est entièrement ouvert et transparent. En outre, vous n’avez pas besoin d’installer Visual Studio pour utiliser le moteur MSBuild : l’exécutable MSBuild.exe fait partie du .NET Framework et vous pouvez l’exécuter à partir d’une invite de commandes. En tant que développeur, vous pouvez créer vos propres fichiers projet MSBuild, à l’aide du schéma XML MSBuild, pour imposer un contrôle sophistiqué et précis sur la façon dont vos projets sont générés et déployés. Ces fichiers projet personnalisés fonctionnent exactement de la même façon que les fichiers projet générés automatiquement par Visual Studio.

Notes

Vous pouvez également utiliser des fichiers projet MSBuild avec le service Team Build dans Team Foundation Server (TFS). Par exemple, vous pouvez utiliser des fichiers projet dans des scénarios d’intégration continue (CI) pour automatiser le déploiement dans un environnement de test lorsque du nouveau code est archivé. Pour plus d’informations, consultez Configuration de Team Foundation Server pour le déploiement web automatisé.

Conventions d’affectation de noms de fichiers projet

Lorsque vous créez vos propres fichiers projet, vous pouvez utiliser n’importe quelle extension de fichier de votre choix. Toutefois, pour faciliter la compréhension de vos solutions par d’autres personnes, vous devez utiliser ces conventions courantes :

  • Utilisez l’extension .proj lorsque vous créez un fichier projet qui génère des projets.
  • Utilisez l’extension .targets lorsque vous créez un fichier projet réutilisable à importer dans d’autres fichiers projet. Les fichiers avec une extension .targets ne créent généralement rien eux-mêmes, ils contiennent simplement des instructions que vous pouvez importer dans vos fichiers .proj.

Intégration avec les technologies de déploiement

Si vous avez travaillé avec des projets d’application web dans Visual Studio 2010, comme ASP.NET applications web et ASP.NET applications web MVC, vous savez que ces projets incluent la prise en charge intégrée de l’empaquetage et du déploiement de l’application web dans un environnement cible. Les pages Propriétés de ces projets incluent les onglets Package/Publier le web et Package/Publier SQL que vous pouvez utiliser pour configurer la façon dont les composants de votre application sont empaquetés et déployés. L’onglet Package/Publier le web s’affiche :

Onglet Package/Publier le web

La technologie sous-jacente derrière ces fonctionnalités est connue sous le nom de pipeline de publication web (WPP). WpP réunit essentiellement MSBuild et Web Deploy pour fournir un processus de génération, de package et de déploiement complet pour vos applications web.

La bonne nouvelle est que vous pouvez tirer parti des points d’intégration que wpp fournit lorsque vous créez des fichiers projet personnalisés pour des projets web. Vous pouvez inclure des instructions de déploiement dans votre fichier projet, ce qui vous permet de générer vos projets, de créer des packages de déploiement web et d’installer ces packages sur des serveurs distants via un seul fichier projet et un seul appel à MSBuild. Vous pouvez également appeler d’autres exécutables dans le cadre de votre processus de génération. Par exemple, vous pouvez exécuter l’outil en ligne de commande VSDBCMD.exe pour déployer une base de données à partir d’un fichier de schéma. Au cours de cette rubrique, vous verrez comment tirer parti de ces fonctionnalités pour répondre aux exigences de vos scénarios de déploiement d’entreprise.

Notes

Pour plus d’informations sur le fonctionnement du processus de déploiement d’applications web, consultez Vue d’ensemble du déploiement de projet d’application web ASP.NET.

Anatomie d’un fichier projet

Avant d’examiner plus en détail le processus de génération, il est utile de prendre quelques instants pour vous familiariser avec la structure de base d’un fichier projet MSBuild. Cette section fournit une vue d’ensemble des éléments les plus courants que vous rencontrerez lorsque vous réviserez, modifiez ou créez un fichier projet. En particulier, vous allez apprendre :

  • Comment utiliser des propriétés pour gérer des variables pour le processus de génération.
  • Comment utiliser des éléments pour identifier les entrées du processus de génération, comme les fichiers de code.
  • Comment utiliser des cibles et destâches pour fournir des instructions d’exécution à MSBuild, à l’aide de propriétés et d’éléments définis ailleurs dans le fichier projet.

Cela montre la relation entre les éléments clés dans un fichier projet MSBuild :

Relation entre les éléments clés dans un fichier projet MSBuild.

Élément Project

L’élément Project est l’élément racine de chaque fichier projet. En plus d’identifier le schéma XML pour le fichier projet, l’élément Project peut inclure des attributs pour spécifier les points d’entrée du processus de génération. Par exemple, dans l’exemple de solution gestionnaire de contacts, le fichier Publish.proj spécifie que la build doit commencer par appeler la cible nommée FullPublish.

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

Propriétés et conditions

Un fichier projet doit généralement fournir un grand nombre d’informations différentes pour générer et déployer vos projets avec succès. Ces informations peuvent inclure des noms de serveurs, des chaînes de connexion, des informations d’identification, des configurations de build, des chemins d’accès aux fichiers source et de destination et toute autre information que vous souhaitez inclure pour prendre en charge la personnalisation. Dans un fichier projet, les propriétés doivent être définies dans un élément PropertyGroup . Les propriétés MSBuild se composent de paires clé-valeur. Dans l’élément PropertyGroup , le nom de l’élément définit la clé de propriété et le contenu de l’élément définit la valeur de la propriété. Par exemple, vous pouvez définir des propriétés nommées ServerName et ConnectionString pour stocker un nom de serveur statique et chaîne de connexion.

<PropertyGroup>    
   <ServerName>FABRIKAM\TEST1</ServerName>
   <ConnectionString>
     Data Source=FABRIKAM\TESTDB;InitialCatalog=ContactManager,...
   </ConnectionString>
</PropertyGroup>

Pour récupérer une valeur de propriété, utilisez le format $(PropertyName). Par exemple, pour récupérer la valeur de la propriété ServerName , tapez :

$(ServerName)

Notes

Vous verrez des exemples montrant comment et quand utiliser des valeurs de propriété plus loin dans cette rubrique.

L’incorporation d’informations en tant que propriétés statiques dans un fichier projet n’est pas toujours l’approche idéale pour gérer le processus de génération. Dans de nombreux scénarios, vous souhaiterez obtenir les informations d’autres sources ou permettre à l’utilisateur de fournir les informations à partir de l’invite de commandes. MSBuild vous permet de spécifier n’importe quelle valeur de propriété en tant que paramètre de ligne de commande. Par exemple, l’utilisateur peut fournir une valeur pour ServerName lorsqu’il exécute MSBuild.exe à partir de la ligne de commande.

msbuild.exe Publish.proj /p:ServerName=FABRIKAM\TESTWEB1

Notes

Pour plus d’informations sur les arguments et les commutateurs que vous pouvez utiliser avec MSBuild.exe, consultez Référence de ligne de commande MSBuild.

Vous pouvez utiliser la même syntaxe de propriété pour obtenir les valeurs des variables d’environnement et des propriétés de projet intégrées. De nombreuses propriétés couramment utilisées sont définies pour vous et vous pouvez les utiliser dans vos fichiers projet en incluant le nom de paramètre approprié. Par exemple, pour récupérer la plateforme de projet actuelle( par exemple, x86 ou AnyCpu), vous pouvez inclure la référence de propriété $(Platform) dans votre fichier projet. Pour plus d’informations, consultez Macros pour les commandes et propriétés de build, Propriétés communes du projet MSBuild et Propriétés réservées.

Les propriétés sont souvent utilisées conjointement avec les conditions. La plupart des éléments MSBuild prennent en charge l’attribut Condition , qui vous permet de spécifier les critères sur lesquels MSBuild doit évaluer l’élément. Par exemple, considérez cette définition de propriété :

<PropertyGroup>
   <OutputRoot Condition=" '$(OutputRoot)'=='' ">..\Publish\Out\</OutputRoot>
   ...
</PropertyGroup>

Lorsque MSBuild traite cette définition de propriété, il vérifie d’abord si une valeur de propriété $(OutputRoot) est disponible. Si la valeur de la propriété est vide, c’est-à-dire que l’utilisateur n’a pas fourni de valeur pour cette propriété, la condition prend la valeur true et la valeur de la propriété est définie sur .. \Publish\Out. Si l’utilisateur a fourni une valeur pour cette propriété, la condition prend la valeur false et la valeur de la propriété statique n’est pas utilisée.

Pour plus d’informations sur les différentes façons dont vous pouvez spécifier des conditions, consultez Conditions MSBuild.

Éléments et groupes d’éléments

L’un des rôles importants du fichier projet est de définir les entrées du processus de génération. En règle générale, ces entrées sont des fichiers : fichiers de code, fichiers de configuration, fichiers de commandes et tous les autres fichiers que vous devez traiter ou copier dans le cadre du processus de génération. Dans le schéma du projet MSBuild, ces entrées sont représentées par des éléments Item . Dans un fichier projet, les éléments doivent être définis dans un élément ItemGroup . Tout comme les éléments Property , vous pouvez nommer un élément Item comme vous le souhaitez. Toutefois, vous devez spécifier un attribut Include pour identifier le fichier ou le caractère générique que l’élément représente.

<ItemGroup>
   <ProjectsToBuild Include="$(SourceRoot)ContactManager-WCF.sln"/>
</ItemGroup>

En spécifiant plusieurs éléments Item portant le même nom, vous créez une liste nommée de ressources. Un bon moyen de voir cela en action consiste à jeter un coup d’œil à l’intérieur de l’un des fichiers projet créés par Visual Studio. Par exemple, le fichier ContactManager.Mvc.csproj dans l’exemple de solution inclut un grand nombre de groupes d’éléments, chacun avec plusieurs éléments Item de nom identique.

<ItemGroup>
   <Reference Include="Microsoft.CSharp" />
   <Reference Include="System.Runtime.Serialization" />
   <Reference Include="System.ServiceModel" />
   ...
</ItemGroup>
<ItemGroup>
   <Compile Include="Controllers\AccountController.cs" />
   <Compile Include="Controllers\ContactsController.cs" />
   <Compile Include="Controllers\HomeController.cs" />
   ...
</ItemGroup>
<ItemGroup>
   <Content Include="Content\Custom.css" />
   <Content Include="CreateDatabase.sql" />
   <Content Include="DropDatabase.sql" />
   ...
</ItemGroup>

De cette façon, le fichier projet indique à MSBuild de construire des listes de fichiers qui doivent être traités de la même façon : la liste référence inclut des assemblys qui doivent être en place pour une génération réussie, la liste Compiler inclut des fichiers de code qui doivent être compilés et la liste Contenu inclut des ressources qui doivent être copiées sans modifications. Nous verrons comment le processus de génération fait référence et utilise ces éléments plus loin dans cette rubrique.

Les éléments Item peuvent également inclure des éléments enfants ItemMetadata . Il s’agit de paires clé-valeur définies par l’utilisateur et qui représentent essentiellement des propriétés spécifiques à cet élément. Par exemple, la plupart des éléments d’élément Compiler dans le fichier projet incluent des éléments enfants DependentUpon .

<Compile Include="Global.asax.cs">
   <DependentUpon>Global.asax</DependentUpon>
</Compile>

Notes

En plus des métadonnées d’élément créées par l’utilisateur, plusieurs métadonnées courantes sont attribuées à tous les éléments lors de leur création. Pour plus d’informations, consultez Métadonnées d’élément connues.

Vous pouvez créer des éléments ItemGroup dans l’élément Project de niveau racine ou dans des éléments Target spécifiques. Les éléments ItemGroup prennent également en charge les attributs Condition , ce qui vous permet d’adapter les entrées au processus de génération en fonction de conditions telles que la configuration du projet ou la plateforme.

Cibles et tâches

Dans le schéma MSBuild, un élément Task représente une instruction de build individuelle (ou une tâche). MSBuild comprend une multitude de tâches prédéfinies. Par exemple :

  • La tâche Copier copie les fichiers vers un nouvel emplacement.
  • La tâche Csc appelle le compilateur Visual C#.
  • La tâche Vbc appelle le compilateur Visual Basic.
  • La tâche Exec exécute un programme spécifié.
  • La tâche Message écrit un message dans un journal.

Notes

Pour plus d’informations sur les tâches disponibles prêtes à l’emploi, consultez Référence des tâches MSBuild. Pour plus d’informations sur les tâches, notamment sur la création de vos propres tâches personnalisées, consultez TÂCHES MSBuild.

Les tâches doivent toujours être contenues dans les éléments Target . Un élément Target est un ensemble d’une ou plusieurs tâches exécutées séquentiellement, et un fichier projet peut contenir plusieurs cibles. Lorsque vous souhaitez exécuter une tâche ou un ensemble de tâches, vous appelez la cible qui les contient. Par exemple, supposons que vous disposiez d’un fichier projet simple qui consigne un message.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Target Name="LogMessage">
      <Message Text="Hello world!" />
   </Target>
</Project>

Vous pouvez appeler la cible à partir de la ligne de commande en utilisant le commutateur /t pour spécifier la cible.

msbuild.exe Publish.proj /t:LogMessage

Vous pouvez également ajouter un attribut DefaultTargets à l’élément Project pour spécifier les cibles que vous souhaitez appeler.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
         DefaultTargets="FullPublish">
   <Target Name="LogMessage">
      <Message Text="Hello world!" />
   </Target>
</Project>

Dans ce cas, vous n’avez pas besoin de spécifier la cible à partir de la ligne de commande. Vous pouvez simplement spécifier le fichier projet, et MSBuild appellera la cible FullPublish pour vous.

msbuild.exe Publish.proj

Les cibles et les tâches peuvent inclure des attributs Condition . Par conséquent, vous pouvez choisir d’omettre des cibles entières ou des tâches individuelles si certaines conditions sont remplies.

En règle générale, lorsque vous créez des tâches et des cibles utiles, vous devez faire référence aux propriétés et aux éléments que vous avez définis ailleurs dans le fichier projet :

  • Pour utiliser une valeur de propriété, tapez $(PropertyName), où PropertyName est le nom de l’élément Property ou le nom du paramètre.
  • Pour utiliser un élément, tapez @(ItemName), où ItemName est le nom de l’élément Item .

Notes

N’oubliez pas que si vous créez plusieurs éléments portant le même nom, vous créez une liste. En revanche, si vous créez plusieurs propriétés portant le même nom, la dernière valeur de propriété que vous fournissez remplacera toutes les propriétés précédentes portant le même nom. Une propriété ne peut contenir qu’une seule valeur.

Par exemple, dans le fichier Publish.proj de l’exemple de solution, examinez la cible BuildProjects .

<Target Name="BuildProjects" Condition=" '$(BuildingInTeamBuild)'!='true' ">
   <MSBuild Projects="@(ProjectsToBuild)"           
            Properties="OutDir=$(OutputRoot);
                        Configuration=$(Configuration);
                        DeployOnBuild=true;
                        DeployTarget=Package"
            Targets="Build" />
</Target>

Dans cet exemple, vous pouvez observer les points clés suivants :

  • Si le paramètre BuildingInTeamBuild est spécifié et a la valeur true, aucune des tâches au sein de cette cible n’est exécutée.

  • La cible contient un seul instance de la tâche MSBuild. Cette tâche vous permet de créer d’autres projets MSBuild.

  • L’élément ProjectsToBuild est passé à la tâche. Cet élément peut représenter une liste de fichiers de projet ou de solution, tous définis par les éléments d’élément ProjectsToBuild au sein d’un groupe d’éléments. Dans ce cas, l’élément ProjectsToBuild fait référence à un seul fichier de solution.

    <ItemGroup>
       <ProjectsToBuild Include="$(SourceRoot)ContactManager-WCF.sln"/>
    </ItemGroup>
    
  • Les valeurs de propriété passées à la tâche MSBuild incluent des paramètres nommés OutputRoot et Configuration. Ces valeurs sont définies sur des valeurs de paramètre si elles sont fournies, ou sur des valeurs de propriété statiques si ce n’est pas le cas.

    <PropertyGroup>
       ... 
       <Configuration Condition=" '$(Configuration)'=='' ">Release
       </Configuration>
       <OutputRoot Condition=" '$(OutputRoot)'=='' ">..\Publish\Out\
       </OutputRoot>
       ...
    </PropertyGroup>
    

Vous pouvez également voir que la tâche MSBuild appelle une cible nommée Build. Il s’agit de l’une des cibles intégrées largement utilisées dans les fichiers projet Visual Studio et disponibles dans vos fichiers projet personnalisés, comme Générer, Nettoyer, Reconstruire et Publier. Vous en apprendrez plus sur l’utilisation de cibles et de tâches pour contrôler le processus de génération, et plus particulièrement sur la tâche MSBuild , plus loin dans cette rubrique.

Notes

Pour plus d’informations sur les cibles, consultez Cibles MSBuild.

Fractionnement des fichiers projet pour prendre en charge plusieurs environnements

Supposons que vous souhaitiez pouvoir déployer une solution dans plusieurs environnements, tels que des serveurs de test, des plateformes intermédiaires et des environnements de production. La configuration peut varier considérablement d’un environnement à l’autre, non seulement en termes de noms de serveurs, de chaînes de connexion, etc., mais aussi potentiellement en termes d’informations d’identification, de paramètres de sécurité et de nombreux autres facteurs. Si vous devez effectuer cette opération régulièrement, il n’est pas vraiment utile de modifier plusieurs propriétés dans votre fichier projet chaque fois que vous basculez dans l’environnement cible. Il ne s’agit pas non plus d’une solution idéale pour exiger qu’une liste infinie de valeurs de propriétés soit fournie au processus de génération.

Heureusement, il existe une alternative. MSBuild vous permet de fractionner votre configuration de build entre plusieurs fichiers projet. Pour voir comment cela fonctionne, dans l’exemple de solution, notez qu’il existe deux fichiers projet personnalisés :

  • Publish.proj, qui contient des propriétés, des éléments et des cibles communes à tous les environnements.
  • Env-Dev.proj, qui contient des propriétés spécifiques à un environnement de développeur.

Notez maintenant que le fichier Publish.proj inclut un élément Import , immédiatement sous la balise Project qui s’ouvre.

<Import Project="$(TargetEnvPropsFile)"/>

L’élément Import est utilisé pour importer le contenu d’un autre fichier projet MSBuild dans le fichier projet MSBuild actuel. Dans ce cas, le paramètre TargetEnvPropsFile fournit le nom de fichier du fichier projet que vous souhaitez importer. Vous pouvez fournir une valeur pour ce paramètre lorsque vous exécutez MSBuild.

msbuild.exe Publish.proj /p:TargetEnvPropsFile=EnvConfig\Env-Dev.proj

Cela fusionne efficacement le contenu des deux fichiers en un seul fichier projet. À l’aide de cette approche, vous pouvez créer un fichier projet contenant votre configuration de build universelle et plusieurs fichiers projet supplémentaires contenant des propriétés spécifiques à l’environnement. Par conséquent, l’exécution d’une commande avec une valeur de paramètre différente vous permet de déployer votre solution dans un autre environnement.

L’exécution d’une commande avec une valeur de paramètre différente vous permet de déployer votre solution dans un autre environnement.

Le fractionnement de vos fichiers projet de cette façon est une bonne pratique à suivre. Il permet aux développeurs de déployer dans plusieurs environnements en exécutant une seule commande, tout en évitant la duplication des propriétés de build universelles entre plusieurs fichiers projet.

Notes

Pour obtenir des conseils sur la façon de personnaliser les fichiers projet spécifiques à l’environnement pour vos propres environnements serveurs, consultez Configuration des propriétés de déploiement pour un environnement cible.

Conclusion

Cette rubrique fournit une présentation générale des fichiers projet MSBuild et explique comment créer vos propres fichiers projet personnalisés pour contrôler le processus de génération. Il a également introduit le concept de fractionnement des fichiers projet en instructions de build universelles et en propriétés de build spécifiques à l’environnement, afin de faciliter la création et le déploiement de projets sur plusieurs destinations.

La rubrique suivante, Présentation du processus de génération, fournit des informations supplémentaires sur la façon dont vous pouvez utiliser les fichiers projet pour contrôler la génération et le déploiement en vous guide tout au long du déploiement d’une solution avec un niveau de complexité réaliste.

En savoir plus

Pour une présentation plus approfondie des fichiers projet et du WPP, consultez Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build by Sayed Ibrahim Hashimi et William Bartholomew, ISBN : 978-0-7356-4524-0.