2
votes

Vérifier si la variable est définie dans PostBuildEvent

J'utilise le PostBuildEvent

<PostBuildEvent>
  IF DEFINED $(MyEnvVar) (
   mkdir "C:\tmp\"
   copy "$(TargetPath)" "$(MyEnvVar)/Addins/Software/bin/$(PlatformName)/$(TargetFileName)"
 )
</PostBuildEvent>

Cet événement fonctionne si mon MyEnvVar est défini. Cependant, j'obtiens une erreur MSB3073 (sortie avec le code 255) si la variable n'est pas définie.

Comment puis-je définir ma tâche PostBuild pour effectuer certaines opérations cmd, (créer des dossiers copier les fichiers comme indiqué ci-dessus), si la variable existe, ou ne rien faire sinon?


0 commentaires

3 Réponses :


1
votes

J'ai copié votre script et rencontré le même problème. Selon le message d'erreur La syntaxe de la commande est incorrecte , quelque chose ne va pas avec la syntaxe, peut-être un espace, une nouvelle ligne dont je ne suis pas sûr :(

Comment puis-je définir ma tâche PostBuild pour effectuer certaines opérations cmd, (create les dossiers copient les fichiers comme indiqué ci-dessus), si la variable existe, ou rien sinon?

Pour contourner le problème: Vous pouvez peut-être supprimer la déclaration Judgment de l'intérieur du PostBuildEvent. Ensuite, utilisez condition msbuild pour juger si la variable est définie ou non, essayez d'utiliser un script comme celui-ci:

<Project...>
    ...
  <!--<PropertyGroup>
    <MyEnvVar>C:\Test</MyEnvVar>
  </PropertyGroup>-->

  <PropertyGroup>
    <PostBuildEvent Condition="$(MyEnvVar)!=''">
      IF NOT EXIST "C:\tmp\" mkdir "C:\tmp\"
      IF NOT EXIST "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" mkdir "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
      copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
    </PostBuildEvent>
  </PropertyGroup>
</Project>

Dans vs, cliquez avec le bouton droit sur le projet et ajoutez-y le script, l'emplacement doit être:

  <!--<PropertyGroup>
    <MyEnvVar>C:\Test</MyEnvVar>
  </PropertyGroup>-->
  <PropertyGroup>
    <PostBuildEvent Condition="$(MyEnvVar)!=''">
      IF NOT EXIST "C:\tmp\" mkdir "C:\tmp\"
      IF NOT EXIST "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" mkdir "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
      copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\"
    </PostBuildEvent>
  </PropertyGroup>

Ensuite, cliquez avec le bouton droit sur le projet et choisissez recharger le projet et vérifiez si cela vous aide à atteindre votre objectif initial.

1. Le PostBuildEvent ne fonctionnera que lorsque MyEnvVar est défini et a sa valeur.

2.Les deux commandes mkdir être appelé lorsque le répertoire C: \ tmp \ et $ (MyEnvVar) \ Addins \ Software \ bin \ $ (PlatformName) \ n'existe pas

3.Ensuite, la commande de copie copiera la sortie de votre projet dans le dossier de destination, je supprime le $ (TargetFileName) car il représente xxx.exe ou xxx.dll, je pense que ce n'est pas nécessaire ou peut-être quoi vous voulez vraiment est $ (As semblyName) . S'il vous plaît laissez-moi savoir si cela aide à résoudre votre problème :)


1 commentaires

Salut @ Lance-Li-MSFT merci pour votre réponse. Il semble que les suggestions Mofi soient bonnes, donc j'ai été utilisé pour résoudre mon problème.



3
votes

Vous ne devriez pas vraiment utiliser d'événements post-build, du tout, jamais . Créez simplement une cible et exécutez-la après la cible de construction. Dans cette cible, faites-lui copier les fichiers souhaités. Quelque chose comme ceci:

<Target Name="CopyMyStuff" AfterTargets="Build" Condition="exists('$(MyEnvVar)')" >
   <Copy SourceFiles="$(TargetPath)" DestinationFolder="$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\" SkipUnchangedFiles="true" />
</Target>

Je pense que cette tâche de copie créera le répertoire s'il n'existe pas. Un joli bonus.


3 commentaires

thaks @C Johnson - puis-je demander pourquoi je ne devrais jamais utiliser d'événements post-build?


C'est comme mélanger de l'argile avec du fer. Pourquoi revenir au passé avec les commandes batch DOS lorsqu'une tâche msbuild peut le faire pour vous?


Vous bénéficiez également d'un excellent support pour la sortie des résultats dans un fichier journal ou sur le terminal.



4
votes

Visual Studio remplace toutes les occurrences de $ (Variable) par la chaîne de la variable Visual Studio dans la valeur de l'élément XML PostBuildEvent avant de créer un fichier de commandes avec le PostBuildEvent texte pour une exécution temporaire après la compilation et le processus de liaison terminé avec succès.

Si une variable Visual Studio référencée comme MyEnvVar n'existe pas du tout, sa référence $ (Variable ) est remplacé par une chaîne vide. Il en résulte ici la ligne de commande:

<PostBuildEvent>
  set "MyEnvVar=$(MyEnvVar)"
  if defined MyEnvVar (
   mkdir "C:\tmp\"
   copy "$(TargetPath)" "$(MyEnvVar)\Addins\Software\bin\$(PlatformName)\$(TargetFileName)"
 )
</PostBuildEvent>

Le processeur de commande Windows exécutant le fichier batch attend le nom d'une variable d'environnement après DEFINED sur ce Condition IF et non une parenthèse ouvrante. Il s’agit d’une erreur de syntaxe détectée par cmd.exe lors de l’évaluation des arguments de la commande IF entraînant la fermeture du traitement du fichier de commandes.

Une solution est using:

IF DEFINED  (

La première ligne attribue la valeur de chaîne actuelle de la variable Visual Studio MyEnvVar à la variable d'environnement MyEnvVar . Par conséquent, la variable d'environnement MyEnvVar est soit définie avec une chaîne à cause de set "MyEnvVar = string value" , soit définitivement non définie (plus) après cette première ligne en cas de variable Visual Studio MyEnvVar n'existe pas ou a une chaîne vide résultant en l'exécution de set "MyEnvVar =" .

La commande IF a toujours une syntaxe valide car maintenant le nom de la variable d'environnement à vérifier pour la définition est toujours spécifié sur cette ligne de commande indépendamment de l'existence et de la valeur de chaîne de la variable Visual Studio MyEnvVar .

Remarque supplémentaire: le séparateur de répertoire sous Windows est \ et non / comme utilisé dans le chemin cible. Le système de fichiers Windows accédant aux fonctions du noyau remplace automatiquement tous les / par \ dans le nom complet du fichier cible dans le cadre d'une correction automatique du chemin du fichier. Mais il est préférable d'écrire le code de l'événement post build avec une syntaxe 100% correcte et ne pas dépendre des corrections automatiques des erreurs sur le chemin du fichier.


0 commentaires