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:
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:
- 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
Because I have 3 files to transform, I'll have to add 3 lines for these 3 files in my build event.