2014-06-30 2 views
2

J'ai un .config dans un projet cible et j'ai besoin d'ajouter une ligne par programmation via une tâche MSBuild.Comment utiliser les tâches MSBuild 'afterbuild' pour éditer un fichier .config?

opérations pseduo comme:

  • trouver le fichier cible
  • déterminer la valeur des attributs pour le nouveau nœud (par exemple 'id' et 'version' pour le nœud 'paquet')
  • insert nouveau noeud noeud parent correct
  • enregistrer les modifications

Le fichier .config à $ TargetProjectDir \ Config \ packages.config:

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
    <package id="ABC" version="1.1.0.4" /> 
    <package id="XYZ" version="2.0.0.0" /> 
</packages> 

a besoin de ressembler à ceci après:

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
    <package id="ABC" version="1.1.0.4" /> 
    <package id="XYZ" version="2.0.0.0" /> 
    <package id="CarDataWidget" version="3.0.0.0" /> 
</packages> 

Jusqu'à présent, je l'ai pensé à utiliser « tâches en ligne », la tâche EXEC et tâche « XmlPoke » mais n'ont pas réussi à obtenir l'un d'eux travaille.

Voici ma tentative avec XmlPoke et XmlPeek:

J'utilisé l'article suivant comme une source d'inspiration sur la façon d'ajouter des nœuds au fichier packages.config: http://weblogs.asp.net/bsimser/appending-nodes-in-xml-files-with-xmlpeek-and-xmlpoke-using-nant

<Target Name="AfterBuild" DependsOnTargets="AddPackage"> 
    </Target> 
    <Target Name="AddPackage"> 
    <!-- Load existing nodes into a Property --> 
    <XmlPeek XmlInputPath="config/packages.config" Query="/packages/package" > 
     <Output TaskParameter="Result" PropertyName="Peeked" /> 
    </XmlPeek> 
    <Message Text="From Peek: $(Peeked)"></Message> 

    <!-- Load new node into Property --> 
    <PropertyGroup> 
     <WidgetName>CarDataWidget</WidgetName> 
     <WidgetVersion>2.0.0.0</WidgetVersion> 
     <NewNode>&lt;package id&#61;&quot;$(WidgetName)&quot; version&#61;&quot;$(WidgetVersion)&quot; /&gt;</NewNode> 

    <!-- Concatenate existing and new node into a Property --> 
     <ConcatenatedNodes>$(Peeked)$(NewNode)</ConcatenatedNodes> 
    </PropertyGroup> 
    <Message Text="New pacakges: $(ConcatenatedNodes)"></Message> 

    <!-- Replace existing nodes with concatenated nodes --> 
    <XmlPoke Value="$(ConcatenatedNodes)" XmlInputPath="config/packages.config" Query="/packages"> 
    </XmlPoke> 
    </Target> 

La sortie de la ci-dessus est la construction:

1>AddPackage: 
1> From Peek: <package id="ABC" version="1.1.0.4" />;<package id="XYZ" version="2.0.0.0" /> 
1> New pacakges: <package id="ABC" version="1.1.0.4" />;<package id="XYZ" version="2.0.0.0" /><package id="CarDataWidget" version="2.0.0.0" /> 
1> C:\_dev\CarDataWidget.csproj(184,14): 
    error MSB4094: "<package id="ABC" version="1.1.0.4" />;<package id="XYZ" version="2.0.0.0" /><package id="CarDataWidget" version="2.0.0.0" />" 
    is an invalid value for the "Value" parameter of the "XmlPoke" task. 
    Multiple items cannot be passed into a parameter of type "Microsoft.Build.Framework.ITaskItem". 
1> 
1>Build FAILED. 

LA QUESTION: Comment l'obtenir pour ajouter à un fichier .config avec des nœuds de paquetages existants ???

+2

Juste curieux: avez-vous pensé à utiliser l'extension SlowCheetah et configuration simples transformations? http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5 Si vous avez toujours besoin de le faire manuellement (par exemple, si de simples transformations basées sur la configuration ne vous conviennent pas), XmlPoke est une option viable, mais vous devriez probablement partager votre code pour la tentative d'utilisation de XmlPoke, donc peple peut vous aider à le faire fonctionner. – Isantipov

Répondre

3

Voici une façon de le faire en utilisant MSBuild Extension Pack.

Définissez les packages et les versions dans le groupe d'éléments NewPackage et ajoutez-les au fichier XML.

<Project 
    ToolsVersion="4.0" 
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks" /> 

    <Target Name="Test" DependsOnTargets="AddPackage"> 
    </Target> 

    <ItemGroup> 
    <NewPackage Include="CarDataWidget"> 
     <Version>3.0.0.0</Version> 
    </NewPackage> 
    <NewPackage Include="FooBarWidget"> 
     <Version>1.2.3.4</Version> 
    </NewPackage> 
    </ItemGroup> 

    <Target Name="AddPackage"> 

    <PropertyGroup> 
     <InputFile>in.xml</InputFile> 
     <OutputFile>out.xml</OutputFile> 
    </PropertyGroup> 

    <Copy SourceFiles="$(InputFile)" DestinationFiles="$(OutputFile)" /> 

    <MSBuild.ExtensionPack.Xml.XmlFile 
     TaskAction="AddElement" 
     File="$(OutputFile)" 
     XPath="//packages" 
     Element="package" 
     Key="id" 
     Value="%(NewPackage.Identity)" /> 

    <MSBuild.ExtensionPack.Xml.XmlFile 
     TaskAction="AddAttribute" 
     File="$(OutputFile)" 
     XPath="//packages/package[@id='%(NewPackage.Identity)']" 
     Key="version" 
     Value="%(NewPackage.Version)" /> 
    </Target> 
</Project> 
0

Jetez un oeil à mon blog http://sedodream.com/2011/12/29/UpdatingXMLFilesWithMSBuild.aspx qui compare les méthodes suivantes.

  1. Utilisez SlowCheetah pour transformer les fichiers pour vous
  2. Utilisez la tâche TransformXML directement
  3. Utilisez le construit (4.0 MSBuild) tâche XmlPoke
  4. Utilisez une tâche tierce partie de la bibliothèque
4

J'ai eu le même problème. J'ai trouvé la solution here.

Le problème est que XmlPoke considère le point-virgule comme un séparateur de valeur.

devrait remplacer:

<NewNode>&lt;package id&#61;&quot;$(WidgetName)&quot; version&#61;&quot;$(WidgetVersion)&quot; /&gt;</NewNode> 

Avec:

<NewNode>&lt%3Bpackage id&#61%3B&quot%3B$(WidgetName)&quot%3B version&#61%3&quot%3$(WidgetVersion)&quot%3 /&gt%3</NewNode> 

doit remplacer chaque virgule par le secuence % 3B

+0

Ceci est la solution au problème d'OP - remplacer le point-virgule; avec% 3B résout le problème –

Questions connexes