MSBuild Script and VS2010 publish apply Web.config Transform

31,286

Solution 1

I was looking for similar information and didn't quite find it, so I did some digging around in the .targets files that come with Visual Studio 2010 and MSBuild 4.0. I figured that was the best place to look for the MSBuild task that would perform the transformation.

As far as I have been able to tell, the following MSBuild task is used:

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

    <UsingTask TaskName="TransformXml"
               AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>

    <PropertyGroup>
        <ProjectPath>C:\Path to Project\Here</ProjectPath>
        <DeployPath>C:\Path to Deploy\There</DeployPath>
        <TransformInputFile>$(ProjectPath)\Web.config</TransformInputFile>
        <TransformFile>$(ProjectPath)\Web.$(Configuration).config</TransformFile>
        <TransformOutputFile>$(DeployPath)\Web.config</TransformOutputFile>
        <StackTraceEnabled>False</StackTraceEnabled>
    </PropertyGroup>


    <Target Name="Transform">
        <TransformXml Source="$(TransformInputFile)"
                      Transform="$(TransformFile)"
                      Destination="$(TransformOutputFile)"
                      Condition="some condition here"
                      StackTrace="$(StackTraceEnabled)" />
    </Target>
</Project>

I have tested the above and can confirm that it works. You might need to tweak the structure a bit to fit with your build script better.

Solution 2

You should be able to accomplish this by using the Package target and specifying the temp directory.

msbuild solution.sln /p:Configuration=Release;DeployOnBuild=true;DeployTarget=Package;_PackageTempDir=..\publish

http://pattersonc.com/blog/index.php/2010/07/15/visual-studio-2010-publish-command-from-msbuild-command-line/

Solution 3

Alternatively, you try using the XDT Transformation Tool:

http://ctt.codeplex.com

I'm using this instead of messing with obscure msbuild targets. Works with app.config not just web.config.

Solution 4

It worked for me with the following change

<MSBuild Projects="$(ProjectFile)"
         Targets="ResolveReferences;_WPPCopyWebApplication"
     Properties="WebProjectOutputDir=TempOutputFolder;OutDir=$(WebProjectOutputDir);Configuration=$(Configuration);" />

From Microsoft.WebApplication.targets file under MsBuild folder

_CopyWebApplication

This target will copy the build outputs along with the 
content files into a _PublishedWebsites folder.

This Task is only necessary when $(OutDir) has been redirected
to a folder other than ~\bin such as is the case with Team Build.

The original _CopyWebApplication is now a Legacy, you can still use it by 
 setting $(UseWPP_CopyWebApplication) to true.
By default, it now change to use _WPPCopyWebApplication target in
 Microsoft.Web.Publish.targets.   
It allow to leverage the web.config trsnaformation.
Share:
31,286
xspydr
Author by

xspydr

Updated on July 05, 2022

Comments

  • xspydr
    xspydr almost 2 years

    So, I have VS 2010 installed and am in the process of modifying my MSBuild script for our TeamCity build integration. Everything is working great with one exception.

    How can I tell MSBuild that I want to apply the Web.conifg transform files that I've created when I publish the build...

    I have the following which produces the compiled web site but, it outputs a Web.config, Web.Debug.config and, Web.Release.config files (All 3) to the compiled output directory. In studio when I perform a publish to file system it will do the transform and only output the Web.config with the appropriate changes...

    <Target Name="CompileWeb">
        <MSBuild Projects="myproj.csproj" Properties="Configuration=Release;" />
    </Target>
    
    <Target Name="PublishWeb" DependsOnTargets="CompileWeb">
        <MSBuild Projects="myproj.csproj"
        Targets="ResolveReferences;_CopyWebApplication"
        Properties="WebProjectOutputDir=$(OutputFolder)$(WebOutputFolder);
                    OutDir=$(TempOutputFolder)$(WebOutputFolder)\;Configuration=Release;" />
    </Target>
    

    Any help would be great..!

    I know this can be done by other means but I would like to do this using the new VS 2010 way if possible

  • xspydr
    xspydr almost 14 years
    this is very similar to the solution I ended up with. The only caveat is that the TransformXml action currently has a bug where it doesn't close the source file and therefore you cannot get rid of the source file. Just something to consider; in my case after I did the transform I wanted to remove both the Debug.config and Release.config files from the deployment directory. To get around this until MS fixes the issue. You can simply copy the source and transform file to a temp directory and then copy the newly transformed file back then you should be able to delete/remove the files...
  • Umar Farooq Khawaja
    Umar Farooq Khawaja almost 14 years
    Yeah, I hit that bug as well when I was trying it out. That is why I had to use $(ProjectPath) and $(DeployPath). Actually, I would suggest using an intermediate location to collect all the build artifacts (which would include the Web.config file) and then deploying to the various web servers from that location containing all of the artifacts. This would save from transforming the Web.config multiple times, assuming all web servers will take the exact same Web.config file.
  • Ryan M
    Ryan M almost 14 years
    +1 for solving my issue from stackoverflow.com/questions/2992778/…
  • stephen
    stephen about 13 years
    Works perfectly for me, great find! The full path of the referenced assembly is here (on x64) "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web‌​.Publishing.Tasks.Dl‌​l".
  • Troy Hunt
    Troy Hunt about 13 years
    Only problem is that this approach won't apply the config transforms to the connection strings.
  • pattersonc
    pattersonc about 13 years
    All web.config transforms should work using this method. Why would connection string specifically not work?
  • Troy Hunt
    Troy Hunt about 13 years
    Because connection strings are handled differently and you'll see a replaceable token instead: troy.hn/gYb7M5 That is unless you override <AutoParameterizationWebConfigConnectionStrings>: troy.hn/mk8iJL
  • jjxtra
    jjxtra over 12 years
    Ugh this puts it in some very random directory many levels deep underneath my bin folder
  • Ben Cull
    Ben Cull almost 12 years
    Like Troy suggests above, I simply added /p:AutoParameterizationWebConfigConnectionStrings=False to my msbuild command and the package now contains the final web.config transforms.
  • SouthShoreAK
    SouthShoreAK almost 10 years
    I'm using nant, and the TransformWebConfig target would not work right for me until I also added the target _WPPCopyWebApplication. This fixed my problem.
  • Sarvesh
    Sarvesh almost 9 years
    The bug @Jason is talking about is now resolved, I am using v12.0 for msbuild.exe and it works like a charm