Le but de cet article est d'en dire un peu plus sur MSBuild, de montrer les cibles et les tâches dans MSBuild, d'apprendre à travailler avec un fichier .csproj et de fournir des liens utiles. Si vous avez un titre plus approprié pour l'article, je serai heureux d'en discuter dans les commentaires.
Le menu
Concepts de base ( Menu )
MSBuild est conçu de telle manière que l'assemblage du projet est divisé en plusieurs étapes.
La cible est une certaine étape (événement) qui se produit lors de l'assemblage d'un projet. Vous pouvez utiliser des cibles standard ou définir les vôtres.
La tâche est une tâche qui peut être effectuée à un certain stade. Vous pouvez utiliser des tâches standard ou créer les vôtres.
Citation de la documentation de ciblage (
https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-targets ):
Cible les tâches de groupe dans un ordre particulier et permet de factoriser le processus de construction en unités plus petites.
Par exemple, une cible peut supprimer tous les fichiers du répertoire de sortie pour préparer la génération, tandis qu'une autre
compile les entrées du projet et les place dans le répertoire vide.
Cycle de vie de construction de MSBuild ( Menu )
Pour MSBuild, Microsoft a défini un certain nombre de cibles standard (dans les fichiers Microsoft.Common.targets, Microsoft.CSharp.targets, etc.). Un grand nombre d'objectifs différents sont définis, mais dans cet article, nous ne nous attarderons pas sur cela en détail. Quelques cibles standard (commandées):
Liste cible (spoiler)- Beforerebuild
- Propre
- Beforebuild
- BuildOnlySettings
- PrepareForBuild
- PreBuildEvent
- ResolveReferences
- PréparerRessources
- ResolveKeySource
- Compiler
- Enregistrement non géré
- GenerateSerializationAssemblies
- Créer des assemblages satellites
- GenerateManifests
- GetTargetPath
- PrepareForRun
- Inscription non gérée
- Incrementalclean
- PostBuildEvent
- Afterbuild
- Afterrebuild
Les cibles BeforeBuild et AfterBuild sont spécifiquement conçues pour être remplacées et peuvent être utilisées.
Je ne recommande pas d'utiliser les cibles restantes de la liste pour que rien ne casse .
Pour une vue plus détaillée de la liste des cibles, vous pouvez utiliser l'option
/ pp : . Grâce à ce paramètre, un fichier sera généré dans lequel toutes les importations seront incluses (y compris les fichiers .targets). Vous pouvez y trouver de nombreuses cibles et variables (merci
aikixd pour l'astuce).
Préparation de l'environnement pour des exemples ( Menu )
Par exemple, vous avez besoin de:
- Environnement de développement installé Visual Studio
- Créez un projet de type Application console nommé MSBuildExample
- Ouvrez le dossier du projet et recherchez-y le fichier MSBuildExample.csproj
- Ouvrez le fichier MSBuildExample.csproj dans le bloc-notes ou un autre éditeur
Dans tous les exemples de cet article, vous devrez modifier le fichier MSBuildExample.csproj. Chaque exemple implique la suppression du code de l'exemple précédent et l'ajout d'un nouveau. Le code doit être ajouté à la fin du fichier .csproj à la dernière ligne contenant la balise de fermeture du projet.
Attention! Dans un fichier .csproj, la casse est importante .
Pour exécuter l'exemple, vous devez exécuter la génération dans l'environnement de développement Visual Studio. Pour certains exemples, vous devrez choisir une configuration de solution.

Le résultat sera affiché dans la fenêtre Sortie de Visual Studio (en bas). Si ce n'est pas le cas, ouvrez-le via les éléments de menu Affichage => Sortie.

Ciblage dans MSBuild ( Menu )
Par exemple, nous utiliserons la tâche
Message , qui affichera des informations dans la fenêtre Sortie de Visual Studio. Comme mentionné précédemment, il existe des cibles standard BeforeBuild et AfterBuild, nous les utiliserons. Pour la formation, lisez la section
Préparation de l'environnement pour des exemples .
Exemple d'utilisation cible (spoiler)Exemple de code:
<Target Name="AfterBuild"> <Message Text="AfterBuild event" Importance="high"></Message> </Target> <Target Name="BeforeBuild"> <Message Text="BeforeBuild event" Importance="high"></Message> </Target>
Résultat d'exécution (inutile exclu):
...
Événement avant construction
...
Événement Afterbuild
...
Comme vous pouvez le voir, la tâche
Message a été exécutée, qui affichait le texte que nous avions spécifié au moment de BeforeBuild et AfterBuild dans la fenêtre Sortie de Visual Studio.
Lors de la définition d'une cible du même nom, elle est écrasée!Exemple de réécriture de cible (spoiler)Exemple de code:
<Target Name="BeforeBuild"> <Message Text="First message" Importance="high"></Message> </Target> <Target Name="BeforeBuild"> <Message Text="Second message" Importance="high"></Message> </Target>
Résultat d'exécution (inutile exclu):
...
Deuxième message
...
Seul le deuxième message a été affiché, car ils utilisaient des cibles du même nom et il a été remplacé par la deuxième valeur.
Création de votre propre cible MSBuild ( menu )
Si les cibles BeforeBuild et AfterBuild ne suffisent pas ou si vous souhaitez que les tâches soient exécutées à une autre étape du cycle de vie de l'assemblage, vous pouvez définir votre propre cible. À ces fins, il existe des paramètres BeforeTargets et AfterTargets.
Exemple de définition de vos propres cibles (spoiler)Exemple de code:
<Target Name="BeforeBuild"> <Message Text="BeforeBuild event" Importance="high"></Message> </Target> <Target Name="MyCustomBeforeTarget" BeforeTargets="BeforeBuild"> <Message Text="MyCustomBeforeTarget event" Importance="high"></Message> </Target> <Target Name="MyCustomAfterTarget" AfterTargets="BeforeBuild"> <Message Text="MyCustomAfterTarget event" Importance="high"></Message> </Target>
Résultat d'exécution (inutile exclu):
...
Événement MyCustomBeforeTarget
Événement avant construction
Événement MyCustomAfterTarget
...
Deux cibles personnalisées ont été définies - MyCustomBeforeTarget et MyCustomAfterTarget.
La cible MyCustomBeforeTarget est exécutée avant la cible BeforeBuild car nous avons spécifié:
BeforeTargets="BeforeBuild"
La cible MyCustomAfterTarget est exécutée après la cible BeforeBuild car nous avons spécifié:
AfterTargets="BeforeBuild"
Tâches dans MSBuild ( Menu )
Cet article ne décrit pas comment vous pouvez écrire vos propres tâches, mais avant d'écrire des
tâches, consultez la liste des
tâches fournie par Microsoft .
Regardons quelques exemples d'utilisation de tâches et de macros.
Paramètre de condition (spoiler)Le paramètre
Condition est présent dans toutes les tâches. Citation de la documentation
docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-task-reference :
Expression booléenne utilisée par le moteur MSBuild pour déterminer si cette tâche sera exécutée.
Exemple de code:
<Target Name="BeforeBuild"> <Message Text="Current configuration is Debug" Condition="'$(Configuration)' == 'Debug'" Importance="high"></Message> <Message Text="Current configuration is Release" Condition="'$(Configuration)' == 'Release'" Importance="high"></Message> </Target>
Si la solution de configuration de débogage est sélectionnée, le résultat ressemblera à ceci (inutile exclu):
...
La configuration actuelle est Debug
...
Si la version de configuration de la solution est sélectionnée, le résultat ressemblera à ceci (inutile exclu):
...
La configuration actuelle est Release
...
Vous pouvez trouver des informations sur la macro $ (Configuration) et d'autres macros dans la section sur les
variables et les macros dans .csproj .
Des informations sur la syntaxe des conditions peuvent être trouvées ici
https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-conditions Définition de variable dans csproj (spoiler)Dans l'exemple ci-dessus, nous avons un texte qui peut être unifié. Pour éviter la duplication, nous placerons le texte du message dans une variable distincte.
Exemple de code:
<PropertyGroup> <MessageText>Current configuration is $(Configuration)</MessageText> </PropertyGroup> <Target Name="BeforeBuild"> <Message Text="$(MessageText)" Condition="'$(Configuration)' == 'Debug'" Importance="high"></Message> <Message Text="$(MessageText)" Condition="'$(Configuration)' == 'Release'" Importance="high"></Message> </Target>
Pour définir votre propre variable, utilisez l'élément
PropertyGroup .
Vérification de l'existence d'un fichier, émission d'une erreur (spoiler)Dans cet exemple, nous effectuons une tâche qui vérifie si le fichier App.Debug.config a été créé. S'il n'est pas créé, nous lançons une erreur. En cas d'erreur, la génération sera arrêtée et l'erreur sera affichée sous forme d'erreurs de compilation dans la fenêtre Liste des erreurs.
Nous utilisons la tâche
Erreur et le paramètre de condition qui nous sont déjà familiers.
Exemple de code:
<Target Name="BeforeBuild"> <Error Condition="!Exists('App.Debug.config')" Text="File App.Debug.config not found"></Error> </Target>
Résultat:

La
clause Exists utilise le chemin relatif du dossier dans lequel se trouve le fichier .csproj. Pour accéder au dossier au-dessus du dossier actuel, utilisez '../'. Si vous devez accéder au sous-dossier, utilisez le format '[DirectoryName] /App.Debug.config'.
Copie de fichiers (spoiler)Dans cet exemple, nous utiliserons la tâche
Copier . À l'aide de la tâche, copiez le fichier App.config dans le dossier bin / [Configuration] / Config dans les deux fichiers App.config et App.test.config.
Exemple de code:
<Target Name="BeforeBuild"> <Copy SourceFiles="App.config;App.config" DestinationFiles="$(OutputPath)/Test/App.config;$(OutputPath)/Test/App.test.config"></Copy> </Target>
La propriété SourceFiles est un tableau de fichiers à télécharger. Indiquez sans guillemets, séparés par des points-virgules.
La propriété DestinationFiles est un tableau de fichiers où les fichiers seront copiés. Indiquez sans guillemets, séparés par des points-virgules.
En savoir plus sur la macro $ (OutputPath) dans la section sur les
variables et les macros dans .csproj .
Variables et macros dans .csproj ( Menu )
Un certain nombre de macros standard peuvent être utilisées dans le fichier .csproj, une liste d'entre elles peut être trouvée ici
https://msdn.microsoft.com/en-us/library/c02as0cs.aspx et ici
https://msdn.microsoft.com/en-us/ bibliothèque / bb629394.aspx . Considérez quelques macros utiles:
- $ (MSBuildToolsPath) - indique le chemin d'accès au dossier MSBuild. Par exemple, C: \ Program Files (x86) \ MSBuild \ 14.0 \ Bin. Lorsque vous combinez un chemin, utilisez cette macro avec une barre oblique. Par exemple, $ (MSBuildToolsPath) \ Microsoft.Web.Publishing.Tasks.dll. Sinon, il peut former le chemin de manière incorrecte et donner une erreur indiquant que le fichier est introuvable.
- $ (OutputPath) - chemin relatif vers le dossier de sortie. Par exemple, bin \ Stage. Utilisez cette macro avec une barre oblique, par exemple, $ (OutputPath) \ $ (TargetFileName) .config.
- $ (TargetFileName) - le nom du fichier de sortie avec l'extension. Par exemple, MSBuildExample.exe. L'extension et le format du nom du fichier de sortie peuvent différer de différents types de projets. À l'aide de cette macro, vous pouvez déterminer en toute sécurité quel sera le nom du fichier de configuration. Il peut être utile pour les transformations de configuration.
- $ (Configuration) est le nom de la configuration actuelle. Par exemple, Release, Debug
- $ (IntermediateOutputPath) - chemin d'accès au dossier obj. Par exemple, obj \ Stage.
Pour définir vos propres paramètres, utilisez le
PropertyGroup . Vous trouverez un exemple de définition de votre propre variable dans la section des
tâches de MSBuild .
Liens ( Menu )