web-dev-qa-db-fra.com

Web.Config se transforme en dehors de Microsoft MSBuild?

Est-il possible d'utiliser la transformation de document XML de Microsoft, pour préparer web.configs, en dehors de MSBuild? Je voudrais utiliser PowerShell pour effectuer ces transformations sans avoir à exécuter cela via le moteur MSBuild. Si Microsoft avait utilisé le XSLT standard, ce serait facile à faire dans PowerShell. D'après ce que je peux dire, je dois utiliser leur C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll qui nécessite un moteur de génération. Merci

52
What Would Be Cool

J'ai créé une petite fonction pour gérer la transformation de documents XML de Microsoft dans PowerShell.

J'ai copié le fichier Microsoft.Web.XmlTransform.dll du dossier de génération de Visual Studio vers le chemin de mon script, mais vous pouvez le référencer depuis le dossier source si vous le souhaitez.

function XmlDocTransform($xml, $xdt)
{
    if (!$xml -or !(Test-Path -path $xml -PathType Leaf)) {
        throw "File not found. $xml";
    }
    if (!$xdt -or !(Test-Path -path $xdt -PathType Leaf)) {
        throw "File not found. $xdt";
    }

    $scriptPath = (Get-Variable MyInvocation -Scope 1).Value.InvocationName | split-path -parent
    Add-Type -LiteralPath "$scriptPath\Microsoft.Web.XmlTransform.dll"

    $xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
    $xmldoc.PreserveWhitespace = $true
    $xmldoc.Load($xml);

    $transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt);
    if ($transf.Apply($xmldoc) -eq $false)
    {
        throw "Transformation failed."
    }
    $xmldoc.Save($xml);
}

Pour transformer web.config à l'aide de web.release.config:

XmlDocTransform -xml "Web.config" -xdt "Web.Release.config"

Vous pouvez également utiliser le script de transformation Xml auto-amorçable de Sayed, qui se chargera d'obtenir le fichier Microsoft.Xml.Xdt.dll pour vous:

https://Gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b

98
Mike DaCosta

La logique de la transformation est contenue à l'intérieur de la tâche TransformXml elle-même. Si vous voulez l'appeler à partir du code, vous devez utiliser l'API MSBuild avec un moteur factice et l'exécuter. J'ai du code pour ça si vous voulez.

Dans votre cas, puisque vous avez mentionné PowerShell, la meilleure chose à faire est de simplement créer un fichier MSBuild wrapper pour appeler la tâche TransformXml. Je dis cela parce que PowerShell est configuré pour fonctionner sous .NET 2.0, mais la tâche TransformXml nécessite .NET 4.0. Afin de l'appeler à partir d'un fichier MSBuild factice, vous pouvez consulter mon blog à http://sedodream.com/2010/04/26/ConfigTransformationsOutsideOfWebAppBuilds.aspx , mais j'ai également collé un échantillon de ce lien ci-dessous.

<Project ToolsVersion="4.0" DefaultTargets="Demo" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
    <UsingTask TaskName="TransformXml"
             AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>

    <Target Name="Demo">
        <TransformXml Source="app.config"
                      Transform="Transform.xml"
                      Destination="app.prod.config"/>
    </Target>
</Project>
12

Microsoft a publié XDT sur codeplex http://xdt.codeplex.com et en tant que package NuGet https://www.nuget.org/packages/Microsoft.Web.Xdt/ . J'ai également créé un cochon NuGet avec une tâche MSBuild, TransformXml et un .exe pour les invoquer https://www.nuget.org/packages/SlowCheetah.Xdt/1.1.6-beta .

Pour PowerShell, j'ai créé un script d'auto-amorçage que vous pouvez utiliser https://Gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b .

Plus d'informations sur les scripts d'auto-amorçage sur http://sedodream.com/2014/07/22/StopCheckinginBinariesInsteadCreateSelfbootstrappingScripts.aspx .

10

Sur la base de la réponse de Michel, j'ai écrit une fonction C # qui accomplira la même chose.

Bien sûr, vous pouvez invoquer la résultante DLL avec PowerShell, mais je cherchais en fait une version entièrement programmatique, alors la voici, au cas où quelqu'un d'autre chercherait une solution similaire:

using Microsoft.Web.XmlTransform;

...

public static void TransformConfig(string configFileName, string transformFileName)
{
     var document = new XmlTransformableDocument();
     document.PreserveWhitespace = true;
     document.Load(configFileName);

     var transformation = new XmlTransformation(transformFileName);
     if (!transformation.Apply(document))
     {
         throw new Exception("Transformation Failed");
     }
     document.Save(configFileName);
}

Vous aurez juste besoin d'inclure une référence aux éléments suivants:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.XmlTransform.dll

9
Sebastian K

J'ai un peu mis à jour le script pour le faire fonctionner avec la dernière version de powershell et le rendre un peu plus facile.

function XmlDocTransform($xml, $xdt)
{
      $scriptpath = $PSScriptRoot + "\"
      $xmlpath = $scriptpath + $xml
      $xdtpath = $scriptpath + $xdt

      if (!($xmlpath) -or !(Test-Path -path ($xmlpath) -PathType Leaf)) {
         throw "Base file not found. $xmlpath";
      }

      if (!($xdtpath) -or !(Test-Path -path ($xdtpath) -PathType Leaf)) {
         throw "Transform file not found. $xdtpath";
      }

      Add-Type -LiteralPath "$PSScriptRoot\Microsoft.Web.XmlTransform.dll"

      $xmldoc = New-Object   Microsoft.Web.XmlTransform.XmlTransformableDocument;
      $xmldoc.PreserveWhitespace = $true
      $xmldoc.Load($xmlpath);

      $transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdtpath);
      if ($transf.Apply($xmldoc) -eq $false)
      {
          throw "Transformation failed."
      }
      $xmldoc.Save($xmlpath);

      Write-Host "Transformation succeeded" -ForegroundColor Green
  }

Et pour appeler la fonction, utilisez

 XmlDocTransform "App.config" "App.acc.config"
6
c_wiz_kid

Jetez un œil à l'utilisation de MSDeploy car il possède des API de script PowerShell qui vous permettent de transformer et de déployer votre package.

Vous pouvez également consulter XML-Document-Transform qui si vous le souhaitez, vous pouvez écrire votre propre code pour effectuer la transformation.

Voici un projet codeplex qui a fait quelque chose de similaire . XDT Transformation Tool

5
SoftwareCarpenter

Tellement étendu pour fonctionner récursivement

    function XmlDocTransform($xml, $xdt)
    {
        if (!$xml -or !(Test-Path -path $xml -PathType Leaf)) {
            throw "File not found. $xml";
        }
        if (!$xdt -or !(Test-Path -path $xdt -PathType Leaf)) {
            throw "File not found. $xdt";
        }
        $scriptPath = (Get-Variable MyInvocation -Scope 1).Value.InvocationName | split-path -parent
        Add-Type -LiteralPath "$scriptPath\Microsoft.Web.XmlTransform.dll"
        $xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
        $xmldoc.PreserveWhitespace = $true
        $xmldoc.Load($xml);
        $transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt);
        if ($transf.Apply($xmldoc) -eq $false)
        {
            throw "Transformation failed."
        }
        $xmldoc.Save($xml);
    }
    function DoConfigTransform($webFolder, $environment)
    {
        $allConfigFiles = Get-ChildItem $webFolder -File -Filter *.config -Recurse
          $transformFiles = $allConfigFiles | Where-Object {$_.Name -like ("*." + $environment + ".config")} | %{$_.fullname}
          ForEach($item in $transformFiles)
          {
            $origFile = $item -replace("$environment.",'')
              XmlDocTransform -xml $origFile -xdt $origFile$item
              #Write-Output ("orig = " + $origFile + ", transform = " + $item)
          }
          cd C:\WebApplications\xxx\xxx\xxx\
          .\PostDeploy.ps1
    }
    DoConfigTransform -webFolder "C:\WebApplications\xxx\xxx\xxx" -environment "xx-xxx-xx"

Ainsi, la logique DoConfigTransform va:

  • Recherche récursivement tous les fichiers de configuration
  • Trouvez tous les modèles de transformation pour l'environnement dans lequel nous sommes #passés en tant que paramètre
  • Pour chaque fichier de transformation, recherchez la configuration correspondante
  • Transformez ensuite
  • Le code exécute un script post-déploiement pour supprimer tous les fichiers de transformation indésirables.
0
Olusegun Orija