«Older Posts - Newer Posts» | rssFeed | My book on MSBuild and Team Build | Archives and Categories Saturday, March 02, 2013

MSDeploy: How to update app settings on publish based on the publish profile

On twitter @vishcious asked me a question related to publishing. The question was

I have a web project that I am publishing to multiple locations using Visual Studio. I have setup multiple profiles and would like to update the values for these app settings differently for each profile. How can I achieve this? I am using parameters.xml to define the MSDeploy parameters.


Note: If you are publishing from VS and don’t care about packaging then you can use profile specific transforms as a simpler way to achieve this result. The rest of the post here assumes you specifically want MSDeploy parameters. To learn more about profile specific transforms see my short video at http://www.youtube.com/watch?v=HdPK8mxpKEI

If you are not familiar you can create custom MSDeploy parameters when you publish/package your application by creating an XML file named parameters.xml in the root of the project. A good resource on this is Vishal’s blog post. I have  created a sample (links below) which demonstrates how to accomplish what the task. Below are the project artifacts that I’ve created to setup the parameters.


<?xml version="1.0"?>
    <add key="email" value="default@example.com"/>
    <add key="url" value="example.com"/>


<?xml version="1.0" encoding="utf-8" ?>
<parameters >

  <parameter name="email" description="description">
    <parameterEntry kind="XmlFile" 
                    match="/configuration/appSettings/add[@key='email']/@value" />

  <parameter name="url" description="description">
    <parameterEntry kind="XmlFile" 
                    match="/configuration/appSettings/add[@key='url']/@value" />


In the parameters.xml file I have defined two new MSDeploy parameters., email and url. This file should be placed in the root of the project directory and it will automatically be picked up by the web publish process. If you are familiar with this you may have noticed that I have left off the DefaultValue attribute here. More to come on that later. Now that we have our parameters defined let’s see what customizations need to be made to the publish profiles (.pubxml files).

You can override the values by populating the MsDeployDeclareParameters item list. Let’s see how to do that. When you create a publish profile in Visual Studio a .pubxml file is written to the folder Properties\PublishProfiles. These are MSBuild files and they are consumed during the build+publish operation. You can customize these files in order to fine tune the publish process. In my sample project I have two publish profiles created; siteone and sitetwo. Both of these are web profiles pointing to Azure Web Sites. In the publish profiles with the samples you will find two sets of elements; properties for publishing and  my parameter customizations. You can see the content of these profiles below, I’ve left off the MSDeploy settings for brevity. Those profiles are shown below.


<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- Web deploy settings here -->  

    <MsDeployDeclareParameters Include="email">
    <MsDeployDeclareParameters Include="url">


<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Web Deploy settings here -->

    <MsDeployDeclareParameters Include="email">
    <MsDeployDeclareParameters Include="url">

In these profiles you can see that I’ve  added a usage of MSDeployDeclareParameters for both parameters in parameters.xml. In each case the value for the Include attribute is the name of the parameter (matches the name attribute in parameters.xml). Along with that I’ve declared a value for the DefaultValue metadata. This will contain the value of the parameter when it is published using that profile.

After publishing siteone the values for the app settings are below.

When publishing with sitetwo the values


That’s it. Now let’s move on to the comment I made previously regarding the DefaultValue attribute that I left off of the parameters.xml file.



When you create parameters and set their values there are a few different places that these can come from including; parameters.xml, auto generated from con strings and custom declared parameters in MSBuild. Because of this the Web Publishing Pipeline has a mechanism to prioritize parameters when there are duplicates. This is facilitated by a Priority metadata value on the MSDeployDeclareParameters item list. If you want to Declare a DefaultValue inside of the parameters.xml file you can do that, but you have to be aware of the impact of that. When you add a DefaultValue parameter in parameters.xml by default those values will take precedence over the items in MSDeployDeclareParameters. Because of that you’ll have to add a Priority value. The way the Priority works is that the item with the lowest priority value for a given parameter will win. The default priority value for params from parameters.xml is –50 (defined in Microsoft.Web.Publishing.targets). Because of that we have to add priority less than –50. For example.

  <MsDeployDeclareParameters Include="email">
  <MsDeployDeclareParameters Include="url">


In this case when I publish these values will override the default value from the parameters.xml.


You can see the latest version of this at https://github.com/sayedihashimi/publish-samples/tree/master/AppSettingsPerProfile.


Sayed Ibrahim Hashimi | @SayedIHashimi | http://msbuldbook.com

Saturday, March 02, 2013 3:36:00 AM (GMT Standard Time, UTC+00:00)  #     | 
Tuesday, February 19, 2013

Videos on Web Publish updates in ASP.NET 2012.2

Earlier today Scott Guthrie blogged about the release of ASP.NET 2012.2 and Web Tools 2012.2. Between this release and the previous publish update in October we have added some really cool publishing features. Today I created some videos of my favorite features. Take a look below.


Quick Publishing

In this video I will show some productivity enhancements that we’ve made to publish that you are going to absolutely love!

New publish support for web site project

Do you use web site projects in Visual Studio? The video below shows how we have unified the publish support for both web application project and web site project.

Updates regarding web.config transforms

We have added some really cool features related to web.config transforms. To be more specific; profile specific transforms and transform previewing. See the video below for more details.

I hope you guys like these features as much as I do. Please let me know what you think.

Sayed Ibrahim Hashimi | @SayedIHashimi | http://msbuildbook.com/

Tuesday, February 19, 2013 9:19:47 AM (GMT Standard Time, UTC+00:00)  #     | 
Tuesday, February 12, 2013

MSBuild: DependsOnTargets versus BeforeTargets, AfterTargets

Today I saw a question on StackOverflow asking about the difference between DependsOnTargets and BeforeTargets/AfterTargets. Below is my response.

In my MSBuild Book I have a section based on how to create reusable elements in MSBuild, if you are interested. I'll give some comments here as well though. This content is different from what the book has.

When creating MSBuild files you should be careful to isolate what versus how. To explain that a bit, lets examine how the managed VS projects work out of the box (which is a great model for reusable elements).

When you create a C#/VB project you get a .csproj file, this .csproj file primarily contains Properties and Items. You will not find a single target in that file. These files contains what will get built (along with some settings relating to the build). At the bottom of the project file you will find an import statement. This import bring in How the project is built.

The files which are imported include:

In this case Microsoft.common.targets defines the overall build process for all the managed languages. Then Microsoft.CSharp.targets (or one of the other lang specific .targets file) fills in the blanks of how to invoke the specific language specific tools.

DependsOnTargets versus Before/AfterTargets

In your answer above you state "I recommend to avoid DependsOnTargets unless it is really really necessary, for instance if two". I disagree with this. Here is my take on DependsOnTargets versus Before/AfterTargets.

Use DependsOnTargets when

Use Before/AfterTargets when

To tease out the difference a bit consider web projects. For web projects there are two workflows that the .csproj/.vbproj take care of: 1. Build 1. Publish

If I want to add a target to the list of targets to be executed before the Build target I can dynamically update the BuildDependsOn property for publish scenarios only. You cannot do this with Before/AfterTargets.

In an ideal world each target would have the following wrt DependsOnTargets.

For example


Unfortunately many targets do not follow this pattern, so DependsOnTargets is dead in the water for many cases.

When I am authoring MSBuild scripts I always use DependsOnTargets unless there is a solid reason why I should chose to use Before/AfterTargets. I feel that (I have no insight on the real reasons to the design as I wasn't with Microsoft at the time) Before/AfterTargets was really created to allow users to inject targets to be executed before/after a target which they did not own, and the creators did not use the pattern above.




msbuild | MSBuild 4.0 Tuesday, February 12, 2013 2:16:30 AM (GMT Standard Time, UTC+00:00)  #     | 
Saturday, February 02, 2013

How to invoke XDT from code

A few weeks ago we released XDT on NuGet, XDT is the technology driving web.config transforms, on NuGet with a license allowing you to redistribute it with your applications. We are working to open source XDT as well so hopefully I will be able to announce that soon as well.

In this post I will show you how you can create a simple application which uses XDT. For this sample we will be creating a console application which will invoke XDT for you. In Visual Studio create a Console Application. I named this project XdtSample. After that we need to add the XDT library. We can easily do this using NuGet. You can execute the following command to insert the package into your project.

 Install-Package Microsoft.Web.Xdt -Pre

Note: after we release the final version you can remove the –Pre flag.

Executing this command will download the XDT assembly as well as add a reference to your project. In program.cs to have the following content.

namespace XdtSample {
    using Microsoft.Web.XmlTransform;
    using System;
    using System.IO;
    using System.Text;

    class Program {
        static void Main(string[] args) {
            if (args == null || args.Length < 3) {

            string sourceFile = args[0];
            string transformFile = args[1];
            string destFile = args[2];

            if (!File.Exists(sourceFile)) { throw new FileNotFoundException("sourceFile doesn't exist"); }
            if (!File.Exists(transformFile)) { throw new FileNotFoundException("transformFile doesn't exist"); }

            using (XmlTransformableDocument document = new XmlTransformableDocument()) {
                document.PreserveWhitespace = true;

                using (XmlTransformation transform = new XmlTransformation(transformFile)) {

                    var success = transform.Apply(document);


                        string.Format("\nSaved transformation at '{0}'\n\n",
                        new FileInfo(destFile).FullName));

                    int exitCode = (success == true) ? 0 : 1;

        static void ShowUsage() {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("\n\nIncorrect set of arguments");
            sb.AppendLine("\tXdtSample.exe sourceXmlFile transformFile destFile\n\n");

The files will be passed in as command line arguments. Below is the usage of the .exe.

xdtsample. sourceFile transformFile destFile 

In the main method here you can see that we load up the source file in an instance of XmlTransformableDocument. We use the XmlTransformation class to represent the transformFile. After applying the transform we simply save the result to the target location.

Pretty simple. Let me know if you have any questions.

I’ve posted this sample on github https://github.com/sayedihashimi/XdtSample.

Sayed Ibrahim Hashimi | http://msbuildbook.com | @SayedIHashimi

XDT Saturday, February 02, 2013 8:51:37 PM (GMT Standard Time, UTC+00:00)  #     | 
Sunday, January 13, 2013

Web packaging fixing the long path issue

Someone sent me an email the other day to discuss some issues with the web packing experience in Visual Studio. One of his concerns were the directory structure in the .zip file that VS generates. If you are not familiar with this I’ll give you a quick overview. In Visual Studio 2012 when you create a web deploy package you typically end up with the full directory structure of your source inside the package. For example I have a project named WebApplication1 located at c:\temp\package\, when I create a package it contains the following files.


These paths can get pretty long depending on where you keep your source. This has been one of my pet peeves as well.

I decided to take a closer look at this and I have a solution. To create a web deploy package in VS you will first create a publish profile for that. When you do this, a .pubxml file will be created for you under Properties\PublishProfiles. This is your publish profile file, its an MSBuild file. You can customize your publish process by editing this file. We will modify this file in order to update these paths in the package.

The best way to solve the issue here is to update the package process to include a replace rule. This replace rule will update the full path into a simple path. We already have this concept baked into our Web Publish Pipeline. The replace rule that we would like to create will replace the paths C:\Temp\package\WebApplication1\obj\Release\Package\PackageTmp with website. Here is how to do it.

Edit the .pubxml file for the profile and add the following before the closing </Project> tag.

  <PackagePath Condition=" '$(PackagePath)'=='' ">website</PackagePath>
  <EnableAddReplaceToUpdatePacakgePath Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='' ">true</EnableAddReplaceToUpdatePacakgePath>
<Target Name="AddReplaceRuleForAppPath" Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='true' ">
  <!-- escape the text into a regex -->
  <EscapeTextForRegularExpressions Text="$(_PkgPathFull)">
    <Output TaskParameter="Result" PropertyName="_PkgPathRegex" />
  <!-- add the replace rule to update the path -->
    <MsDeployReplaceRules Include="replaceFullPath">


Let me break this down a bit. You create the target AddReplaceRuleForAppPath, and inject that into the package process by adding it to PackageDependsOn property. Once this target is executed it will add a replace rule into the MSDeployReplaceRules item group. The replace rule added is equivalent to the command line switch shown below.


Now when I create a package the contents are.


That's a lot better! If you try this out let me know if you have any issues.


Sayed Ibrahim Hashimi | @SayedIHashimi

Sunday, January 13, 2013 1:37:29 AM (GMT Standard Time, UTC+00:00)  #     | 
Sunday, January 06, 2013

Command line web project publishing

With the release of VS2012 we have improved the command line publish experience. We’ve also made all the web publish related features available for VS2010 users in the Azure SDK.

The easies way to publish a project from the command line is to create a publish profile in VS and then use that. To create a publish profile in Visual Studio right click on the web project and select Publish. After that it will walk you though creating a publish profile. VS Web publish profile support the following publish methods.

Command line publishing is only supported for Web Deploy, Web Deploy Package, and File System. If you think we should support command line scenarios for other publish methods the best thing to do would be to create a suggestion at http://aspnet.uservoice.com. If there is enough interest we may work on that support.

Let’s first take a look at how you can publish a simple Web project from the command line. I have created a simple Web Forms project and want to publish that. I’ve created a profile named SayedProfile. In order to publish this project I will execute the following command.

msbuild MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=<profile-name> /p:Password=<insert-password> /p:VisualStudioVersion=11.0

In this command you can see that I have passed in these properties;

You may not have expected the VisualStudioVersion property here. This is a new property which was introduced with VS 2012. It is related to how VS 2010 and VS 2012 are able to share the same projects. Take a look at my previous blog post at http://sedodream.com/2012/08/19/VisualStudioProjectCompatabilityAndVisualStudioVersion.aspx. If you are building the project file, instead of the solution file then you should always set this property.

If you are publishing using the .sln file you can omit the VisualStudioVersion property. That property will be derived from the version of the solution file itself. Note that there is one big difference when publishing using the project or solution file. When you build an individual project the properties you pass in are given to that project alone. When you build from the command line using the solution file, the properties you have specified are passed to all the projects. So if you have multiple web projects in the same solution it would attempt to publish each of the web projects.

FYI in case you haven’t already heard I’m working on an update to my book. More info at msbuildbook.com

Sayed Ibrahim Hashimi | @SayedIHashimi

msbuild | MSBuild 4.0 | MSDeploy | web | Web Deployment Tool Sunday, January 06, 2013 2:56:37 AM (GMT Standard Time, UTC+00:00)  #     | 
Friday, January 04, 2013

SlowCheetah support for Azure Worker Roles

I have had a number of request to get SlowCheetah working for Azure Worker Roles. I think I have it working now. I have not yet released the support to the download page yet but after the support is verified I will update the release.

If you would like to try out a build which has support to transform app.config, as well as other XML files, for Azure Worker Roles you can find the VSIX at https://dl.dropbox.com/u/40134810/SlowCheetah/issue-44/SlowCheetah-issue-44.zip. After installing for worker role projects you can create XML transforms for app.config, and any other XML file. When you publish to azure, or create a package your files should be transformed.

More info on this on the following issues.

BTW if you are interested in my upcoming MSBuild book checkout msbuildbook.com

Sayed Ibrahim Hashimi @SayedIHashimi

azure | SlowCheetah Friday, January 04, 2013 8:14:45 AM (GMT Standard Time, UTC+00:00)  #     | 
Sunday, December 30, 2012

Info on upcoming MSBuild book

I wanted to let everyone know that William Bartholomew and I are working to update our MSbuild book. This will be the third edition. We are going at this a bit different than our second edition. Instead of doing a complete rewrite of the previous book, we have decided that we will release a small book to supplement the existing book. We did this for a number of reasons but it boiled down to the fact that most of the existing content is still accurate. So it would be better to release a small update just covering new stuff. This is going to be really great for everyone who already owns the second edition. You can quickly learn all the new material, and it will be much cheaper than a full sized book. I’m not sure of the cost yet but I will keep you all posted.

For more info on the book please checkout out my new site msbuildbook.com. At that site you can get info on the second edition as well as the third. You can get info on downloading samples for both versions of the book as well. FYI the source for the msbuildbook.com site is available at https://github.com/msbuild-book/msbuildbook.com.

Sayed Ibrahim Hashimi @SayedIHashimi

Sunday, December 30, 2012 1:35:13 AM (GMT Standard Time, UTC+00:00)  #     | 
Monday, December 24, 2012

SlowCheetah build server support updated

A while back I blogged about how to setup SlowCheetah on a Build server. The solution was good but it was a bit unwieldy and error prone, especially those who are not comfortable with MSBuild (this solution still works and is still a good approach for some scenarios). I’ve made this much easier, but wasn’t able to make it as easy as what I wanted. The solution that I choose is using NuGet. Ideally you’d be able to install the SlowCheetah NuGet package into a project, enable package restore and the check in your code. Unfortunately due to how NuGet package restore is implemented this flow is not currently possible. Hopefully in the near future Nuget will better support these scenarios. For now we will have to work with the solution below.


The transformations are executed when your project is built. The way that this works is that when you use the SlowCheetah VS add-in to enable transformations, your project file is modified to import an additional MSBuild .targets file which knows how to do the transformations. This .targets file is placed in your %localappdata% folder. When you add the SlowCheetah NuGet package to your project, the .targets file (and supporting files) are downloaded to the packages folder. Your project is also modified to look at the packages folder for the .targets file which is imported.

For build server scenarios, when using NuGet for this it’s a bit of a chicken and egg problem. Let me clarify, we are using NuGet to update the build process for your project. If a solution is using NuGet, you will need to enable NuGet Package Restore. This is what will enable your NuGet packages to be download during build.

Package Restore is implemented to restore NuGet packages for each project whenever it is built. This is accomplished by adding an Import into your project to NuGet.targets. This works beautiful for the majority of cases, but fails completely if you are trying to update the build process for a given project with NuGet. When the build for a project starts if the the imported .targets file do not exist on disk they are not imported. You can visualize this flow as.


We need to find a way to get the packages restored, before your project is built. We can achieve this by executing a build which will be used to simply restore our packages. Now let’s see how we can workaround this issue.


We need to find a way to restore the packages before the project is built. The easiest way to do this is to add a dummy solution to be built before your actual solution/project. Follow these steps.

1. Install the SlowCheetah NuGet package into the project using SlowCheetah.

You can do this by using the Package Manager Console, and executing the command Install-Package SlowCheetah –pre. Note: after the package is released you can remove the –pre.

2. Enable Package Restore for the solution

You can do this by right clicking on the solution and selecting Enable NuGet Package Restore.

3. Configure build server to build restorePackage.proj before your solution

As described we need a new solution that can be used to restore the required packages. When you install SlowCheetah it will automatically create a packageRestore.proj file in the root of your project. You can use this to easily restore your NuGet packages. All you need to do is to build this file before you build your solution or build script. If you are using Team Build this is pretty easy. Edit the build definition and then add packageRestore.proj to the Items to Build list. You can find this on the Process tab.



Make sure that packageRestore.proj is above (built before) your solution.


With these changes when the empty solution is built, it will restore the SlowCheetah .targets file. Then the target solution will be built, the .targets file will already be downloaded and your transforms will execute as needed.

I will work with the NuGet team to see if there is something better that can be done here. I will keep you all posted if there is any update.I would love if you tried out this new support and let me know if you have any issues with it.

Sayed Ibrahim Hashimi | @SayedIHashimi

SlowCheetah | Visual Studio 2010 | Visual Studio 2012 Monday, December 24, 2012 9:37:24 PM (GMT Standard Time, UTC+00:00)  #     | 
Wednesday, December 19, 2012

How to sync multiple folders with Web Deploy (MSDeploy)

I received a customer email and one of the things that he wants to be able to do is sync multiple folders. I thought I’d share with you what I wrote to him.

From: Sayed Hashimi
Sent: Tuesday, December 18, 2012 11:28 PM

You actually can do this, but it’s not based on skips, it’s an opt-in approach. What I mean is that you would have to specify all the folders that you wanted to sync.

MSDeploy is a provider based model. There is an composite provider, manifest, which can be used when multiple providers are required. In your case the actual provider that you want to use is contentPath. This is the provider that knows how to sync folders. If you want to sync multiple folders you can create a source manifest which has the source folders and a dest manifest which has all the target folders.

In my example I have the following folders.

I only want to sync 01 and 03 so I create the manifest with the following content.

<?xml version="1.0" encoding="utf-8"?>
  <contentPath path="C:\Temp\publish\Source\01"/>
  <contentPath path="C:\Temp\publish\Source\03"/>

The dest manifest file will contain.

<?xml version="1.0" encoding="utf-8"?>
  <contentPath path="C:\Temp\publish\Dest\01"/>
  <contentPath path="C:\Temp\publish\Dest\03"/>

Then to do the sync you can use the command.

msdeploy -verb:sync -source:manifest="C:\Temp\publish\SourceManifest.xml" -dest:manifest="C:\Temp\publish\DestManifest.xml" -enableRule:DoNotDelete -useCheckSum -disableRule:BackupRule

You can see that I use the manifest provider for both the source and the dest. A few things to note.

Drawbacks from this approach

How you can make this even better

The real issue I have with this approach is that it requires both a source & dest manifest. If you can easily auto generate these files from a list of shares that would be great. If you are maintaining these files “by hand” you should be careful to make sure both files are updated.

With a bit of more work you can boil it down to a single source manifest if you have a common root folder, and you want the files to be reflected in the same relative structure underneath that. They way that you would do this is to use the MSDeploy auto provider trick. With MSDeploy you can pass –dest:auto and MSDeploy will essentially reflect the source settings to the destination. You can then create an MSDeploy parameter which will be used to update the path of that common root folder.

If you want to go down this option it will be a bit more complex. I’d be willing to walk you through it if you’d be willing to blog about it afterwards J

Sayed Ibrahim Hashimi | @SayedIHashimi

MSDeploy Wednesday, December 19, 2012 7:34:19 AM (GMT Standard Time, UTC+00:00)  #     |