Build Automation for Windows Presentation Framework (WPF) & Silverlight Applications

Nov 09, 2011
Oshyn Labs
In this post, I want to share a way to do automated builds for Microsoft WPF Applications. The idea is to easily compile and deploy this type of application when the same code needs to be deployed to different environments, but applying different configuration files depending on the environment. For this technique I am going to use NAnt and the .NET framework 4.0.

Suppose that you have a .NET application and you want to deploy the same code to different environments. The difference between deploying to one environment and another is the configuration files that need to be applied. So in this case, the app.config file values changes according to which environment deploy. Consider that your configuration file have an entry like:

<add key="serverUri" value="http://www.integration.com"/>

Where the value of “serverUri ” needs to change according to which environment is under compilation. To archive that we need to create a parameterized NANT script that receives as a parameter which environment to compile and applies the desired configuration file.

The first thing that I suggest is to create a Configuration Manager structure inside your code versioning. So suppose that your project code is on svn in the location:

trunk\Code\<Project Name>

In your versioning repository you should create a folder structure like:

trunk\ConfigurationManagement\BuildFiles\ (Put here the nant scripts)
trunk\ConfigurationManagement\Environments\<Project Name>\app.format.config
trunk\ConfigurationManagement\Environments\<Project Name>\Integration\ EnvBuild.property
trunk\ConfigurationManagement\Environments\<Project Name>\QA\ EnvBuild.property
trunk\ConfigurationManagement\Environments\<Project Name>\Production\ EnvBuild.property

Where app.format.config is the configuration file of the application, and it contains tokens like:
<add key="serverUri" value="http://${dnsServer}"/>.

The value of “serverUri” is defined inside each property file EnvBuild.property and this value changes according to which environment is under compilation. So each EnvBuild.property file contains the entries respectively:
<property name="dnsServer" value="integration.oshyn.com" />
<property name="dnsServer" value="qa.oshyn.com" />
<property name="dnsServer" value="production.oshyn.com" />

In order to do that here is a very simple example of a NAnt script that needs to be located inside the folder trunk\ConfigurationManagement\BuildFiles\default.build.

The following command should be used to execute the NAnt script from cmd:

nant -buildfile:default.build -D:ftpserver=ftp.host.com -D:ftpuser=user -D:ftppass=password -D:ftpdestinationprefix=/PublishedApplication "-D:ftpsourceprefix=c:\installer" -D:project.name=Player -D:propertyfile=EnvBuild.property -D:sourcefile=app.format.config -D:environmenttag=QA -D:destinationfile=app.config ftpdeploy

Important Components Requirements:

1)   You need to have installed and configured NAnt in order to build your .NET 4.0 projects. Check http://nant.sourceforge.net/.
2)   You need to install and configure NAntContrib in order to do some operation on your scripts like loadtasks, msbuild, etc… Check http://nantcontrib.sourceforge.net/
3)   For the FTP deployments, you need to you use NAnt Task http://www.spinthemoose.com/~ftptask/.
4)    The machine that is going to compile the .NET application needs to have all the necessary .NET components required for the compilation like the .NET framework, etc.


Important Notes about the Sample NAnt Script

1)   The NAnt Settings section provides information of the NAnt task to include like the FTPTask and NAntContrib. Also it sets the target .NET framework version.
2)   To define a property in a scrip you can use
<property name="project.name" value="invalid.project" overwrite="false"/>, the overwrite=false shows that if that property were not defined upper or was not passed as parameter like -D:project.name=Player, the value assigned is going to be invalid.project.
3)   The target “build” has a dependency of the target “configMerge” in charge of the replacements of the tokens defined on the EnvBuild.property files into the app.format.config according to the property “environmenttag”. That dependency means that first is going to be executed the target “configMerge” and then the target “build”. Target build is executed by default if you do not specify any target at the moment of the execution of the NAnt script.
4)   Inside the msbuild task, the example is performing a ClickOnce compilation. For more details check http://msdn.microsoft.com/en-us/library/ms165431%28v=vs.80%29.aspx.
5)   The target “ftpdeploy” have a dependency to the target “build” that means that the target “configMerge”, “build” are going to be executed before the target “ftpdeploy”.

As I exposed here, this is an example of how to automate deployments for WPF applications. Notice that this script sample receives the parameter environmenttag to decide which configuration file to apply and deploy.  In order to automate the execution of NAnt commands you can create .bat files that download the latest code using a svn client and execute the NAnt command.