2010-05-20 6 views
3

déjà permuté à MS Connect:Redéfinition MSBuildExtensionsPath dans la tâche MSBuild est floconneuse

https://connect.microsoft.com/VisualStudio/feedback/details/560451

Je cherche à passer outre la propriété $ (MSBuildExtensionsPath) lors de la construction d'une solution contenant un C# application web projet via msbuild. Je le fais parce qu'un fichier csproj d'application web importe le fichier "$ (MSBuildExtensionsPath) \ Microsoft \ VisualStudio \ v9.0 \ WebApplications \ Microsoft.WebApplication.targets". Ce fichier est installé par Visual Studio à l'emplacement $ (MSBuildExtensionsPath) standard (C: \ Program Files \ MSBuild). Je voudrais éliminer la dépendance sur ce fichier étant installé sur la machine (je voudrais garder mes serveurs de construction aussi "propres" que possible). Pour ce faire, je voudrais inclure le Microsoft.WebApplication.targets dans le contrôle de la source avec mon projet, puis remplacer $ (MSBuildExtensionsPath) afin que le csproj importera cette version incluse de Microsoft.WebApplication.targets. Cette approche me permet de supprimer la dépendance sans me demander de modifier manuellement le fichier csproj de l'application Web.

Ce schéma fonctionne correctement lorsque je compile mon fichier de solution à partir de la ligne de commande, en fournissant la valeur personnalisée de $ (MSBuildExtensionsPath) à la ligne de commande à msbuild via l'indicateur/p. Toutefois, si je tente de générer la solution à l'aide de la tâche MSBuild dans un fichier de projet msbuild personnalisé (remplaçant MSBuildExtensionsPath à l'aide de l'attribut "Properties"), il échoue car le fichier csproj de l'application Web tente d'importer les Microsoft.WebApplication.targets emplacement "standard" Microsoft.WebApplication.targets (C: \ Program Files \ MSBuild). Notamment, si je lance msbuild en utilisant la tâche "Exec" dans mon fichier de projet personnalisé, cela fonctionne. Encore plus particulièrement, la première fois que je lance la construction en utilisant la tâche "MSBuild" APRÈS avoir exécuté la construction en utilisant la tâche "EXEC" (ou directement à partir de la ligne de commande), la construction fonctionne.

Quelqu'un at-il déjà vu un comportement comme celui-ci? Suis-je fou? Est-ce que quelqu'un est au courant de la cause première de ce problème, une solution de contournement possible, ou si c'est un bug légitime dans MSBuild?

Procédure pour reproduire:

1) Créer une nouvelle solution vide MSVS 2008 (Fake.sln)

2) Ajouter un nouveau C# application Web à la solution (WebApplication1.csproj)

3) Fermer MSVS

4) Copiez le contenu de "C: \ Program Files \ MSBuild \" dans un répertoire appelé "MSBuildExtensions" dans le répertoire contenant votre solution. 5) renommer le répertoire "C: \ Programmes \ MSBuild \ Microsoft \ VisualStudio \ v9.0 \ WebApplications" afin que WebApplication1.csproj ne puisse pas importer les fichiers Microsoft.WebApplication.targets à partir de cet emplacement.

6) Créez un fichier de projet MSBuild personnalisé appelé "TestBuild.proj" dans le même répertoire que la solution. Il devrait avoir le contenu suivant:

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="BuildMSBuild"> 

<PropertyGroup> 
    <MSBuildExtensionsPath>$(MSBuildProjectDirectory)\MSBuildExtensions\</MSBuildExtensionsPath> 
    <BuildThis>Fake.sln</BuildThis> 
</PropertyGroup> 

<Target Name="BuildMSBuild"> 
    <MSBuild Projects="$(BuildThis)" Properties="MSBuildExtensionsPath=$(MSBuildExtensionsPath);" Targets="Clean" /> 
    <MSBuild Projects="$(BuildThis)" Properties="MSBuildExtensionsPath=$(MSBuildExtensionsPath);"/> 
</Target> 

</Project> 

7) exécuter « msbuild TestBuild.proj » à partir d'une invite de commande VSM (note: la construction peut réussir la première fois, mais échouera si vous exécutez plus d'une fois)

+0

Pourriez-vous publier votre fichier de projet msbuild personnalisé, pour voir ce qui ne va pas. –

+0

Ajout d'instructions de repro à la question. Merci! –

+0

Impossible de repro sur ma machine. Attention: si votre projet est créé sur une machine 64 bits, la propriété est nommée: MSBuildExtensionsPath32 et fonctionne comme MSBuildExtensionsPath –

Répondre

3

Ceci est un bogue dans MSBuild 3.5 mais il est corrigé dans MSBuild 4.

Si vous le pouvez, passez à MSBuild 4 (vous pouvez toujours compiler vos projets 3.5), sinon vous devrez override the property dans le fichier de projet.

3

Cela fonctionne très bien si vous remplacez MSBuildExtensionsPath directement dans le fichier de l'application Web .csproj.

<PropertyGroup> 
    <MSBuildExtensionsPath>C:\Users\madgnome\Desktop\msbuild</MSBuildExtensionsPath> 

    <!-- It works too with relative path --> 
    <!--<MSBuildExtensionsPath>..\msbuild</MSBuildExtensionsPath>--> 
</PropertyGroup> 

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> 
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" /> 
+0

Oui, c'est vrai - j'ai essayé ça.Désolé de ne pas le mentionner dans le post. Je préférerais ne pas avoir à modifier le fichier csproj, puisque je voudrais que mon système de construction fonctionne correctement avec les projets "par défaut" créés par visual studio, et je ne veux pas avoir à faire face à un studio visuel qui me crie dessus (ou d'autres devs) quand ils ouvrent ce fichier csproj "modifié". –

3

Avez-vous essayé de définir la variable d'environnement MSBuildExtensionPath dans l'invite CMD, puis d'exécuter votre build?

Par exemple:

C:> SET MSBuildExtensionsPath = C: \ My \ MSBuild \ Extensons

ensuite sur ce fichier de projet:

vous obtiendrez la sortie suivante:

c: \ Utilisateurs \ chuckeng \ Desktop \ ConsoleApplication1> «C: \ Windows \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe» my.proj Microsoft (R) Build Engine Version 3.5.30729.4926 [Microsoft .NET Framework, Version 2.0. 50727.4927] Copyright (C) Microsoft Corporation 2007. Tous droits réservés.

La construction a démarré le 25/06/2010 13:04:05. Projet "c: \ my.proj" sur le noeud 0 (cibles par défaut). MSBuildExtensionsPath = "C: \ Mon \ MSBuild \ Extensons" Terminé Projet de construction "c: \ my.proj" (cibles par défaut).

La construction a réussi. 0 Avertissement (s) 0 erreur (s)

Temps écoulé 00: 00: 00,03

Cela fonctionne de v4.0 ainsi. Bien que, le support est généralement meilleur dans v4.0 pour des choses comme ceci. Et, v4.0 est 100% rétrocompatible (bogues non résistants). Ainsi, vous pouvez construire vos projets v3.5 et antérieurs avec v4.0. Sélectionnez simplement ToolsVersion 3.5. msbuild my.proj /tv:3.5

Hope this helps ...

Chuck Angleterre Visual Studio Program Manager - MSBuild

1

Je ne sais pas si cela pourrait aider quelqu'un à l'avenir, mais j'ai été en mesure d'utiliser ce qui suit en haut de mon fichier et cela fonctionne comme je l'attendais dans les deux environnements de construction 32 et 64 bits.

<PropertyGroup> 
    <MSBuildExtensionsPath Condition=" '$(MSBuildExtensionsPath64)' != '' ">$(MSBuildExtensionsPath64)</MSBuildExtensionsPath> 
</PropertyGroup> 
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/> 
Questions connexes