web-dev-qa-db-fra.com

Pouvez-vous empêcher MSBuild.exe d'exécuter les événements de construction?

Je construis un certain nombre de projets à l'aide d'un script, et l'utilisation occasionnelle d'événements de construction personnalisés pose de nombreuses difficultés pour le système de construction. Si cela est possible, j'aimerais invoquer MSBuild.exe de manière à bloquer l'exécution de tout événement de génération. À long terme, cela n’est pas un problème pour l’automatisation de la construction: les émetteurs de projets comportant des événements de construction sont prévenus que ce type de contrefaçon est contraire aux règles.

En bref, existe-t-il un moyen d'appeler MSBuild qui empêche l'exécution de toute étape de construction personnalisée, le cas échéant?

METTRE À JOUR:

J'avais envisagé de modifier sur place (automatiquement) les fichiers du projet, mais je préférerais utiliser l'équivalent en ligne de commande du paramètre "Excluded From Build" (voir les options Build Events) sur Yes pour chacun des trois événements.

48
Sniggerfardimungus

Pre/PostBuildEvents sont des propriétés. Par conséquent, pour les remplacer, définissez-les à partir de la ligne de commande sur une chaîne vide.

msbuild foo.sln /p:PreBuildEvent= /p:PostBuildEvent=
84
radical

Vous pouvez également rendre la propriété conditionnelle

<PreBuildEvent Condition="'$(BuildingInsideVisualStudio)' == '' Or '$(BuildingInsideVisualStudio)' == true"> ... </PreBuildEvent>
12
Sarin

Ce que je voudrais faire est de définir un nouveau fichier .proj, disons C:\Data\SupressBuildEvents.proj Et il contiendrait:

<Project xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
    <Target Name="PostBuildEvent"/>

    <Target Name="PreBuildEvent" />
</Project>

Ensuite, vous devez spécifier que ces fichiers sont importés après Microsoft.Common.targets. Pour ce faire, définissez la propriété bien connue CustomAfterMicrosoftCommonTargets sur le chemin de ce fichier. Laissons donc votre script de construction dans un fichier nommé MyBuild.proj que vous invoqueriez comme suit:

msbuild MyBuild.proj /p:CustomAfterMicrosoftCommonTargets="C:\Data\SupressBuildEvents.proj
"

Ainsi, MSBuild importera votre fichier après l’importation du fichier Microsoft.Common.targets. Il remplacera les cibles PostBuildEvent et PreBuildEvent et leur fera ne rien faire.

Maintenant, si vos fichiers MyBuild.proj utilisent la tâche MSBuild pour créer d’autres cibles, vous devez également leur transmettre cette propriété comme suit:

<Project xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <ProjectsToBuild Include=" FILL THIS IN "/>
    </ItemGroup>

    <Target Name="YourTarget">
        <MSBuild Projects="@(ProjectsToBuild)"
                 Properties="CustomAfterMicrosoftCommonTargets=$(CustomAfterMicrosoftCommonTargets)"/>
    </Target>

</Project>

Cela est nécessaire car, par conception, les propriétés du script parent ne sont pas transmises aux générations exécutées par la tâche MSBuild.

10

Il semble que la réponse diffère selon le type de projet.

Pour les projets C/C++ (.vcxproj), vous pouvez supprimer PostBuildEvent sur la ligne de commande avec /p:PostBuildEventUseInBuild=false, comme le suggère AndreiM. 

(Définir /p:PostBuildEvent sur une chaîne vide ne fonctionne pas pour les projets C++ et je ne trouve pas d'autre moyen de remplacer la commande post-build).

Pour les projets C # (.csproj), vous pouvez supprimer le PostBuildEvent sur la ligne de commande avec /p:PostBuildEvent=, comme le suggèrent la plupart des autres répondants. 

9
dtopham75

Vous pouvez également définir les propriétés dans votre tâche MSBuild:

<MSBuild 
  Projects="$(MSBuildProjectDirectory)\YourProject.csproj" 
  Properties="Configuration=$(BuildConfiguration);BuildingFromBuildProjXml=true;PreBuildEvent=;PostBuildEvent=" 
  ContinueOnError="false" />
4
derFunk

J'ai aussi joué un peu avec msbuild foo.vcxproj /p:PreBuildEvent= /p:PostBuildEvent=, mais pour moi cela n'a pas fonctionné, probablement parce que j'utilise des fichiers d'accessoires personnalisés.

Ce que j’ai trouvé fonctionner était cependant /p:PostBuildEventUseInBuild=false

3
AndreiM
<Target Name="PreBuild" BeforeTargets="PreBuildEvent" 
Condition="'$(VisualStudioDir)' != ''">

L'ajout de cette condition à la cible pour la pré-construction dans le fichier csproj du projet est la seule solution qui a fonctionné pour moi. J'ai rencontré ce problème en essayant d'automatiser une construction dans VSTS dans laquelle je voulais ignorer l'événement PreBuild défini dans le fichier du projet csproj. À l'aide de Visual Studio 2017, un projet .NET Core 2.0. 

J'ai essayé les suggestions de ligne de commande msbuild répertoriées ici, mais aucune d'entre elles ne fonctionnait pour moi. 

0
Neil Schurrer

Dans certains projets C #, j'ai besoin de PostBuildEvent pour Visual Studio, mais pas pour MSBuild et TFS. Pour cela, j'ajoute PostBuildEvent dans VS. Il définit le code ci-dessous dans le fichier .csproj:

  <PropertyGroup>
    <PostBuildEvent>*... my custom post build event ....*</PostBuildEvent>
  </PropertyGroup>

après cela, j’ajoute les codes ci-dessous à .csproj: 

  <Target Name="BeforeBuild">
      <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'false' Or '$(BuildingInsideVisualStudio)' != 'true'">
        <PostBuildEvent></PostBuildEvent>
      </PropertyGroup>
  </Target>

Ce code définit PostBuildEvent sur vide et se produit uniquement dans les cibles MSBuild et TFSBuild BeforeBuild. C'est simple, permanent, pas besoin de définir des paramètres et fonctionne bien.

0
AhmadYo

Par défaut, lorsque vous importez Microsoft.Common.targets, vous obtenez

<PropertyGroup>
    <BuildDependsOn>
        BeforeBuild;
        CoreBuild;
        AfterBuild
    </BuildDependsOn>
</PropertyGroup>

Je pense que vous pouvez peut-être simplement le remplacer par

<PropertyGroup>
    <BuildDependsOn>
        CoreBuild
    </BuildDependsOn>
</PropertyGroup>

désactiver ces événements pré/post build. (Vous ne savez pas si vous devez insérer cela dans votre fichier .proj avant ou après l'importation, ou si vous devez modifier Microsoft.Common.targets pour avoir un tel effet. Vous n'avez pas le temps d'expérimenter maintenant ...)

0
Brian