Tuesday, April 24, 2012

Transform Web.config for debugging using MsBuild 4.0 and VS.NET 2010



This is the old topic and there are quite a few post about this. I found following articles are quite helpfull and actually, I based on their help to make a solution that fit my need:
http://geekswithblogs.net/EltonStoneman/....aspx
http://stackoverflow.com/questions/2905151

Well, in my project, I have a 3 different configuration files which are web.config, appSettings.config and Autofac.config that need to be transformed when I debug. There are many settings need to be changed between those configurations so doing it manually is not an interesting job.



I want a simple solution that can be reused for other project, and on top of it, I don't want to unload my project, put some chunk of Msbuild tasks to it to do the job. Therefore, an external msbuild script seems to be a nice option. Then what I actually need to do is modify the build event of the project to call MsBuild command to transform these things. However, I don't want my hack to affect the build process on server so I use a environment variable which is only available on my machine to enable the transformation.

So using this way, I have to aware 3 following pointss:

  • Work only for MSbulid 4.0 since I'm using a feature of this version
  • The Web.config for instance will be overwrite everytime I build the project, and I should not checkin these changes.
  • I should have a Web.Debug.config to switch everthing back to normal in Debug configuration.

Here is the Msbuild Script:
<!--  To use:
- Put this file at project folder
- Set DeveloperMachine to enable transforming on current machine, otherwise it will be ignored
- Set following command as the Post build event:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild $(ProjectDir)TransformXml.msbuild /p:ProjectPath=$(ProjectDir);Configuration=$(ConfigurationName);ConfigFile=Web.config
-->
<Project ToolsVersion="4.0"
         DefaultTargets="Execute"
         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 Condition=" '$(ProjectPath)' == '' ">.\</ProjectPath>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <ConfigFile Condition=" '$(ConfigFile)' == '' ">Web.config</ConfigFile>
        <ConfigFileName>$(ConfigFile.Substring(0, $(ConfigFile.IndexOf('.'))))</ConfigFileName>
        <ConfigFileExtension>$(ConfigFile.Substring($(ConfigFile.LastIndexOf('.'))))</ConfigFileExtension>
        <StackTraceEnabled>False</StackTraceEnabled>
        
        <TransformInputConfigFile>$(TEMP)\$(ConfigFileName)_Temp$(ConfigFileExtension)</TransformInputConfigFile>
        <TransformConfigFile>$(ProjectPath)$(ConfigFileName).$(Configuration)$(ConfigFileExtension)</TransformConfigFile>
        <TransformOutputConfigFile>$(ProjectPath)$(ConfigFileName)$(ConfigFileExtension)</TransformOutputConfigFile>            
    </PropertyGroup>


    <Target Name="Transform" Condition="'$(DeveloperMachine)' == 'True'" >
        <Copy
            SourceFiles="$(TransformOutputConfigFile)"
            DestinationFiles="$(TransformInputConfigFile)"
            OverwriteReadOnlyFiles="True"
        />
        
        <TransformXml Source="$(TransformInputConfigFile)"
                      Transform="$(TransformConfigFile)"
                      Destination="$(TransformOutputConfigFile)"
                      StackTrace="$(StackTraceEnabled)" />                    
        
    </Target>      
    
    <Target Name="Init" Condition="'$(DeveloperMachine)' != 'True'">
        <Message Text="Set system environment [DeveloperMachine] to True to transform $(TransformOutputConfigFile) while debugging !!!" />                
    </Target>
    
    <Target Name="Execute" DependsOnTargets="Init;Transform" />        
            
</Project>

As you see in the comment, to use this script:
  1. Put this file at project folder
  2. Set DeveloperMachine to enable transforming on current machine, otherwise it will be ignored
  3. Set following command as the Post build event:

  4. C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild $(ProjectDir)TransformXml.msbuild /p:ProjectPath=$(ProjectDir);Configuration=$(ConfigurationName);ConfigFile=Web.config


Because I have 3 files to transform, I'll have to add 3 lines for these 3 files in my build event.


Cheers.

0 comments:

Post a Comment