Comment exécuter des événements de post-génération de Visual Studio pour la génération de débogage uniquement


592

Comment puis-je limiter mes événements post-build à ne s'exécuter que pour un seul type de build?

J'utilise les événements pour copier les fichiers DLL dans un répertoire virtuel IIS local, mais je ne veux pas que cela se produise sur le serveur de génération en mode de publication.

Réponses:


746

Les événements avant et après construction s'exécutent en tant que script de commandes. Vous pouvez faire une déclaration conditionnelle sur $(ConfigurationName).

Par exemple

if $(ConfigurationName) == Debug xcopy something somewhere

7
étrange, c'est peut-être juste moi mais j'ai essayé d'ajouter la condition if, et maintenant j'obtiens cette erreur - erreur terminée avec le code 255
Michael L

101
J'ai trouvé que la commande entière doit être sur une seule ligne ou vous obtiendrez "quitté avec le code 255"
Robin Minto

7
vous pouvez également utiliser des gotos / labels pour une solution plus complète (voir ma réponse du 24 juillet)
CestLaGalere

11
et vous pouvez utiliser des crochets avec la commande if (voir ma réponse pour un exemple)
gbjbaanb

1
Vous devez utiliser "xcopy / Y", afin que le fichier soit écrasé dans le répertoire cible.
Matthias

521

Pour info, vous n'avez pas besoin d'utiliser goto. La commande shell IF peut être utilisée avec des crochets ronds:

if $(ConfigurationName) == Debug (
  copy "$(TargetDir)myapp.dll" "c:\delivery\bin" /y
  copy "$(TargetDir)myapp.dll.config" "c:\delivery\bin" /y
) ELSE (
  echo "why, Microsoft, why".
)

62
Puis-je également ajouter, pour faire attention à la parenthèse d'ouverture qui doit suivre immédiatement l'instruction if, comme si c'était sur la ligne suivante un code d'erreur serait produit
wonea

37
Utilisez "$(ConfigurationName)"(notez les guillemets) si vous obtenez le code d'erreur 255
jgauffin

20
notez que si vous utilisez "" autour de $ (ConfigurationName), vous avez aussi besoin de guillemets autour du mot Debug - les instructions IF de la commande shell sont très .. littérales ... quand il s'agit de comparaisons de chaînes.
gbjbaanb

5
Remarque, pour se débarrasser du 255, j'ai dû utiliser "" autour de $ (ConfigurationName) ET supprimer les espaces autour de la condition, par exemple si "$ (ConfigurationName)" == "Release" <- Pas d'espaces autour ==
fhilton

15
Dans mon cas, Visual Studio 2017 $(ConfigurationName)est vide (ligne de commande d'événement post-build). if "$(Configuration)" == "Debug"travaillé pour moi. BTW, si vous voulez faire quelque chose dans toutes les autres configurations, utilisez if NOT "$(Configuration)" == "Debug".
Ralf Hundewadt

125

Ajoutez votre événement post-build comme d'habitude. Enregistrez ensuite votre projet, ouvrez-le dans le Bloc-notes (ou votre éditeur préféré) et ajoutez une condition au groupe de propriétés PostBuildEvent. Voici un exemple:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <PostBuildEvent>start gpedit</PostBuildEvent>
</PropertyGroup>

5
Cela fonctionne mais cela vous oblige à effectuer tout votre travail de conception pour les événements dans la source du fichier de projet. D'autres déclarations d'événements de génération conditionnelles sont également masquées par l'EDI.
Joseph Daigle

3
Je dois dire que c'est la meilleure réponse pour moi, la méthode préférée n'a tout simplement pas fonctionné.
Michael L

8
Vous n'avez pas besoin de l'ouvrir dans le Bloc-notes, vous pouvez rester dans Visual Studio. Vous pouvez cliquer avec le bouton droit sur le fichier de projet, cliquer sur "Décharger le projet", puis cliquer de nouveau avec le bouton droit et cliquer sur "Modifier". Vous pouvez maintenant modifier le fichier {{csproj}} avec une coloration syntaxique. Cliquez de nouveau avec le bouton droit de la souris, mais cliquez maintenant sur "Recharger le projet" pour recharger.
Abel

1
Cette approche n'a pas étendu les macros dans la commande PostBuildEvent elle-même lorsque je l'ai essayée. cd "$(ProjectDir)"étendu à cd "".
Darryl

3
Dans VS 2017, vous pouvez également le faire avec <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$(ConfigurationName) == Debug"> <Exec Command="your command"/></Target>. Les variables de macro et tout fonctionnent normalement.
SC

106

Sinon (étant donné que les événements sont placés dans un fichier de commandes, puis appelés), utilisez ce qui suit (dans la zone d'événements de génération, pas dans un fichier de commandes):

if $(ConfigurationName) == Debug goto :debug

:release
signtool.exe ....
xcopy ...

goto :exit

:debug
' Debug items in here

:exit

De cette façon, vous pouvez avoir des événements pour n'importe quelle configuration, et toujours le gérer avec les macros plutôt que d'avoir à les passer dans un fichier batch, rappelez-vous que %1c'est $(OutputPath), etc.


6
Si vous avez la possibilité de regarder une partie de votre code dans le réflecteur, le compilateur transforme beaucoup d'instructions switch / case en goto.
StingyJack

10
La plupart des compilateurs traduisent le code en instructions plus simples, comme goto. Et l'ingénierie inverse ne peut pas rassembler des instructions plus simples dans les "belles" instructions plus complexes que vous préféreriez voir. Je ne vois pas comment Microsoft nous oblige à utiliser goto, ni comment cela est pertinent pour cet article.
TamusJRoyce

1
@StingyJack: si vous regardez le code compilé, vous verrez que tout cela est transformé en instructions JMP :) Je me fiche de ce que fait le compilateur sous les couvertures, tant que j'écris du code bien lisible. (pas que l'utilisation de goto n'est pas toujours très facile à lire)
gbjbaanb

Si je mets mes commandes post-build dans un batch, j'obtiens ce message d'erreur lorsque je presse la build:Error 1 The command "C:\MyProject\postbuild.bat" exited with code 99. MyProject
Sebastian

4
si vous le souhaitez, vous pouvez supprimer ifet utilisergoto :$(ConfigurationName)
Calimero100582

15

Visual Studio 2015: La syntaxe correcte est (gardez-la sur une seule ligne):

if "$(ConfigurationName)"=="My Debug CFG" ( xcopy "$(TargetDir)test1.tmp" "$(TargetDir)test.xml" /y) else ( xcopy "$(TargetDir)test2.tmp" "$(TargetDir)test.xml" /y)

Pas d'erreur 255 ici.


3
garder sur une seule ligne
Eric Bole-Feysot

Travailler bien. Tks
Vinicius Gonçalves

1
Votre technique conditionnelle a fonctionné le mieux pour moi. Cependant, cela a fonctionné encore mieux sans conditions du tout et c'est beaucoup plus concis. copier "$ (ProjectDir) \ .. \ $ (ConfigurationName) \ MyFileName" "$ (TargetDir)"
shawn1874

1
Votre script est correct, mais mon script permet de copier différents fichiers pour différentes configurations.
Eric Bole-Feysot

8

Depuis Visual Studio 2019, le .csprojformat moderne prend en charge l'ajout d'une condition directement sur l' Targetélément:

<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Debug'">
    <Exec Command="nswag run nswag.json" />
</Target>

L'interface utilisateur ne fournit pas un moyen de configurer cela, mais elle semble laisser l' Configurationattribut en place en toute sécurité si vous apportez des modifications via l'interface utilisateur.


Cela a fonctionné pour moi dans VS 2019, merci!
BrandoTheBrave

Cela mérite vraiment d'être plus élevé, ils devraient également mettre à jour l'interface utilisateur pour vous permettre de marquer la configuration de construction ou au moins d'ajouter la condition à partir des propriétés csproj.
DeadlyChambers

4

Vous pouvez transmettre le nom de la configuration au script post-génération et l'archiver pour voir s'il doit s'exécuter.

Passez le nom de la configuration avec $(ConfigurationName).

La vérification est basée sur la façon dont vous implémentez l'étape post-construction - ce sera un argument de ligne de commande.


-1

Cela fonctionne pour moi dans Visual Studio 2015.

Je copie tous les fichiers DLL d'un dossier situé dans un dossier de bibliothèque au même niveau que mon dossier de solution dans le répertoire cible du projet en cours de construction.

Utiliser un chemin relatif depuis mon répertoire de projet et remonter la structure des dossiers en deux étapes avec .. \ .. \ lib

MySolutionFolder
.... MyProject
Lib

if $(ConfigurationName) == Debug (
xcopy /Y "$(ProjectDir)..\..\lib\*.dll" "$(TargetDir)"
) ELSE (echo "Not Debug mode, no file copy from lib")

-2

Comme tout paramètre de projet, les événements de génération peuvent être configurés par configuration. Sélectionnez simplement la configuration que vous souhaitez modifier dans la liste déroulante de la boîte de dialogue Pages de propriétés et modifiez l'étape de post-génération.


10
Les événements de génération ne sont spécifiques à aucune configuration lorsqu'ils sont créés dans l'EDI.
Joseph Daigle

1
Ne fonctionne pas non plus dans VS2015. Non configurable par configuration.
willem

2
Cela s'applique uniquement aux projets C ++ dans Visual Studio, pas C #
bytecode77

-3

Dans Visual Studio 2012, vous devez utiliser (je pense que dans Visual Studio 2010 aussi)

if $(Configuration) == Debug xcopy

$(ConfigurationName) a été répertorié en tant que macro, mais il n'a pas été attribué.

Entrez la description de l'image ici

Comparer: macros pour les commandes et les propriétés de génération


7
Vous souhaitez utiliser ConfigurationName. Cette image est ... vraiment difficile à comprendre avec tout le flou.
Rabbin furtif
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.