2009-09-02 8 views
14

Je veux déclarer trois propriétés dans mon fichier MSBuild et écraser une propriété avec la valeur d'une autre (en fonction de la cible appelée), mais je n'arrive pas à comprendre comment procéder. Mon fichier de construction ressemble à ceci:Ecraser des propriétés avec MSBuild

<PropertyGroup> 
    <DeployPath_TEST>\\test-server-path\websites\mysite</DeployPath_TEST> 
    <DeployPath_LIVE>\\live-server-path\websites\mysite</DeployPath_LIVE> 
    <DeployPath></DeployPath> 
</PropertyGroup> 

<Target Name="Deploy-TEST"> 
    <PropertyGroup> 
     <DeployPath>$(DeployPath_TEST)</DeployPath> 
    </PropertyGroup> 
    <CallTarget Targets="Deploy-Sub"/> 
</Target> 

<Target Name="Deploy-LIVE"> 
    <PropertyGroup> 
     <DeployPath>$(DeployPath_TEST)</DeployPath> 
    </PropertyGroup> 
    <CallTarget Targets="Deploy-Sub"/> 
</Target> 

<Target Name="Deploy-Sub"> 
    <Message Text="Deploying to $(DeployPath)"/> 
    <MSBuild Projects="MySolution.csproj" Targets="Rebuild" /> 

    <ItemGroup> 
    <MyFiles Include="**\*"/> 
    </ItemGroup> 

    <Copy SourceFiles="@(MyFiles)" 
     DestinationFiles="@(MyFiles->'$(DeploymentPath)\%(RecursiveDir)%(FileName)%(Extension)')"/> 

</Target> 

En ce moment je suis en train de re-déclarer la propriété est mise en valeur en conséquence il, mais cela ne fonctionne pas.

Répondre

13

Mehmet a raison sur la façon de définir une valeur de propriété d'une autre propriété, mais il y a un bug/fonctionnalité dans MSBuild ce qui signifie que si vous appelez CreateProperty et CallTarget dans la même cible, votre nouvelle propriété ne sera pas être globalement disponible pour d'autres cibles (described here).

Voici donc la solution finale au problème:

<PropertyGroup> 
    <DeployPath_TEST>\\test-server-path\websites\mysite</DeployPath_TEST> 
    <DeployPath_LIVE>\\live-server-path\websites\mysite</DeployPath_LIVE> 
    <DeployPath></DeployPath> 
</PropertyGroup> 

<Target Name="SetDeployPath-TEST"> 
    <CreateProperty Value="$(DeployPath_TEST)"> 
    <Output TaskParameter="Value" PropertyName="DeployPath"/> 
    </CreateProperty> 
</Target> 

<Target Name="Deploy-TEST"> 
    <CallTarget Targets="SetDeployPath-TEST"/> 
    <CallTarget Targets="Deploy-Sub"/> 
</Target> 

<Target Name="Deploy-Sub"> 
    <Message Text="Deploying to $(DeployPath)"/> 
    <MSBuild Projects="MySolution.csproj" Targets="Rebuild" /> 

    <ItemGroup> 
    <MyFiles Include="**\*"/> 
    </ItemGroup> 

    <Copy SourceFiles="@(MyFiles)" 
    DestinationFiles="@(MyFiles->'$(DeploymentPath)\%(RecursiveDir)%(FileName)%(Extension)')"/> 

</Target> 
+0

Merci, c'était utile. Je suis encore un peu novice en matière de dosage et MS ne fait pas du bon travail en expliquant les concepts liés à mon avis. Une note de plus. En fait, je suis parti sans créer une propriété globale; cela rétrécit un peu le contexte, il est donc plus facile de lire le code: la cible A appelle les cibles B et C. B définit une propriété de liste et C effectue un traitement par lots sur la valeur de cette propriété. comme mighter a noté que la définition de la propriété dans la même cible n'a pas fonctionné. J'espère que ça aide quelqu'un; J'ai passé 3-4 heures à essayer de comprendre cela avant de trouver ce post. – AlexeiOst

+0

Encore un point, vous dites que vous recevez une notification que seul Cat a changé, avez-vous essayé d'enregistrer les modifications? Est-ce que ça marche? (J'en doute) –

8

Vous pouvez utiliser la tâche CreateProperty pour remplacer la valeur d'une propriété existante.

<Target Name="Deploy-LIVE"> 
    <CreateProperty Value="$(DeployPath_LIVE)"> 
    <Output PropertyName="DeployPath" TaskParameter="Value"/> 
    </CreateProperty> 
    <CallTarget Targets="Deploy-Sub"/> 
</Target> 
+0

Cela ne semble pas fonctionner pour moi. Je peux utiliser la valeur de la propriété DeployPath immédiatement après le bloc CreateProperty, mais elle perd sa valeur dans la cible Deploy-Sub. –

+2

Haa, vient de trouver cet article http://weblogs.asp.net/bhouse/archive/2006/03/20/440648.aspx décrivant un bug/fonctionnalité avec la tâche CreateProperty. –

+0

Intéressant Je ne connaissais pas ce bug. J'ai utilisé CreateProperty avant mais apparemment rien de nécessaire pour accéder à la propriété écrasée en dehors de la cible qui l'a écrasée. Merci. –

4

J'évite généralement la tâche CallTarget. Il vaut mieux utiliser les dépendances cibles.

+0

Pourriez-vous élaborer un peu? Pourquoi est-ce mieux pour vous? –

+2

@HaymoKutschbach à cause de ce bug http://sedodream.com/PermaLink,guid,dd6cb1db-c0e4-47f7-ad84-6e59ff6b03d0.aspx et je pense que CallTarget va à l'encontre du modèle mental de la façon dont msbuild devrait être utilisé. MSBuild est déclaratif, CallTarget est très impératif. Cela dit, il y a des cas où c'est nécessaire, mais vous devriez préférer DependsOn avant CallTarget. –

+0

Merci! Je suis d'accord et il semble que l'équipe msbuild encourage aussi DependsOn à activer les propriétés globales dans les projets importés. –

0

De plus, vous pouvez utiliser comme suit:

<PropertyGroup> 
    <DeployPath_TEST>\\test-server-path\websites\mysite</DeployPath_TEST> 
    <DeployPath_LIVE>\\live-server-path\websites\mysite</DeployPath_LIVE> 
    <DeployPath></DeployPath> 
</PropertyGroup> 

<Target Name="SetDeployPath-TEST"> 
    <CreateProperty Value="$(DeployPath_TEST)"> 
    <Output TaskParameter="Value" PropertyName="DeployPath"/> 
    </CreateProperty> 
</Target> 

<Target Name="Deploy-Sub" DependsOnTargets="SetDeployPath-TEST"> 
    <Message Text="Deploying to $(DeployPath)"/> 
    <MSBuild Projects="MySolution.csproj" Targets="Rebuild" /> 

    <ItemGroup> 
    <MyFiles Include="**\*"/> 
    </ItemGroup> 

    <Copy SourceFiles="@(MyFiles)" 
    DestinationFiles="@(MyFiles->'$(DeploymentPath)\%(RecursiveDir)%(FileName)%(Extension)')"/> 

</Target> 
Questions connexes