Web.Config transforms outside of Microsoft MSBuild?

后端 未结 8 2058
情书的邮戳
情书的邮戳 2020-11-29 18:13

Is it possible to use Microsoft\'s XML document transform, for preparing web.configs, outside of MSBuild? I would like to use PowerShell to do these transform without having

相关标签:
8条回答
  • 2020-11-29 18:32

    The logic of the transformation is contained inside of the TransformXml task itself. If you want to call it from code you would have to use the MSBuild API with a mock engine and execute it. I have some code for this if you want.

    In your case since you mentioned PowerShell the best thing for you to do is to just create a wrapper MSBuild file to invoke the TransformXml task. I say this because PowerShell is configured to run under .NET 2.0, but the TransformXml task requires .NET 4.0. In order to call it from a dummy MSBuild file you can check my blog at http://sedodream.com/2010/04/26/ConfigTransformationsOutsideOfWebAppBuilds.aspx, but I've also pasted a sample from that link below.

    <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>
    

    For mono, this should work (tested on mono 6.4, macos, 2019) :

    <Project DefaultTargets="TransformConfig" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <UsingTask TaskName="TransformXml"
        AssemblyFile="$(MSBuildSDKsPath)/Microsoft.NET.Sdk.Publish/tools/net46/Microsoft.NET.Sdk.Publish.Tasks.dll"/>
      <PropertyGroup>
        <TransformSource>Web.config</TransformSource>
        <Transformer>Web.Live.config</Transformer>
        <Destination>Output.Web.config</Destination>
      </PropertyGroup>
      <Target Name="TransformConfig">
        <Message Text="From TransformSource : $(TransformSource)" />
        <Message Text="Using Transform : $(Transformer)" />
        <Message Text="Output : $(Destination)" />
        <Message Text="MSBuildSDKsPath=$(MSBuildSDKsPath)" Condition="'$(MSBuildSDKsPath)' != ''" />
        <TransformXml Source="$(TransformSource)" Transform="$(Transformer)" Destination="$(Destination)"/>
      </Target>
    </Project>
    

    which you can run with just msbuild or supply parameters with

    msbuild /p:TransformSource=... /p:Transformer=...
    
    0 讨论(0)
  • 2020-11-29 18:35

    Take a looked at using MSDeploy since it has PowerShell scripting APIs that allow you to transform and deploy your package.

    You can also look at XML-Document-Transform which if you wanted to you can write your own code to perform the Transform.

    Here is a codeplex project that did something similar.XDT Transformation Tool

    0 讨论(0)
  • 2020-11-29 18:40

    Microsoft has posted XDT to codeplex http://xdt.codeplex.com and as a NuGet package https://www.nuget.org/packages/Microsoft.Web.Xdt/. I have also created a NuGet pig with an MSBuild task, TransformXml, and an .exe to invoke them https://www.nuget.org/packages/SlowCheetah.Xdt/1.1.6-beta.

    For PowerShell I've created a self-bootstrapping script which you can use https://gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b.

    More about self bootstrapping scripts at http://sedodream.com/2014/07/22/StopCheckinginBinariesInsteadCreateSelfbootstrappingScripts.aspx.

    0 讨论(0)
  • 2020-11-29 18:48

    I came to this post well after it original posting but it helped resolve my issue so I thought I'd put my solution (based on the solution above) here for anyone having the same problem with a current visual studio / msbuild install.

    Currently in VS build time transforms are done using the SlowCheetah nuget pkg. If you can rely on this package in your project you can use the script I have placed below and it will automatically find the required assembly based on the installed cheetah version and perform your transform as needed.

    Hope this helps someone.

    param(  
      [ValidateScript({$(Test-Path $_) -eq $true})]
      [string] $NuGetRootPath,
    
      [ValidateScript({$(Test-Path $_) -eq $true})]
      [string] $BaseFile,
    
      [ValidateScript({$(Test-Path $_) -eq $true})]
      [string] $TransformFile,
    
      [string] $TargetPath
    )
    
    "[INFO] Creating Custom XML Transform..." | Out-Default   
    "[INFO] ==> Source:    $BaseFile" | Out-Default   
    "[INFO] ==> Transform: $TransformFile" | Out-Default   
    "[INFO] ==> Target:    $TargetPath" | Out-Default   
    
    $cheetahDir = Join-Path $NuGetRootPath *SlowCheetah* | Resolve-Path | Select-Object -Last 1 -ExpandProperty Path
    $xformDll = Join-Path $cheetahDir "tools\Microsoft.Web.XmlTransform.dll" | Resolve-Path | Select-Object -ExpandProperty Path
    Add-Type -LiteralPath $xformDll
    
    $xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
    $xmldoc.PreserveWhitespace = $true
    $xmldoc.Load($BaseFile);
    
    "[INFO] Running Transform..." | Out-Default
    $transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($TransformFile);
    if ($transf.Apply($xmldoc) -eq $false) {
        throw "[ERROR] Transformation failed."
    }
    
    $xmldoc.Save($TargetPath);
    "[INFO] Transformation Complete..." | Out-Default
    
    0 讨论(0)
  • 2020-11-29 18:50

    Based on Michel's answer I wrote a C# function that will accomplish the same.

    Of course you could invoke the resultant DLL with PowerShell, but I was actually looking for a fully programatic version, so here it is, in case anybody else is looking for similar solution:

    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);
    }
    

    You will just need to include reference to following:

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

    0 讨论(0)
  • 2020-11-29 18:53

    I created a small function to handle Microsoft's XML Document Transform in PowerShell.

    I copied the Microsoft.Web.XmlTransform.dll file from Visual Studio build folder to my script's path, but you can reference it from the source folder if you'd like.

    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);
    }
    

    To transform web.config using web.release.config:

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

    Alternatively, you can use Sayed's self-bootstraping Xml Transform script, which will take care of getting the Microsoft.Xml.Xdt.dll for you:

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

    0 讨论(0)
提交回复
热议问题