Automate Build for a ClickOnce Application Hosted on CodePlex using MSBuild

This is what I wanted my automated build to do:

  1. Get the latest version from CodePlex
  2. Update the version number in AssemblyInfo.cs
  3. Build the project
  4. Check-in the updated AssemblyInfo.cs
  5. Label the project with the version number
  6. Publish the ClickOnce package to my webserver

In order to achieve this I used the CodePlex Source Control Client (cpc.exe) to perform the get latest and check-ins. I was not able to complete #5 as the cpc client does not provide labelling. Maybe once the SvnBridge supports it I can upgrade this guide to use a SubVersion client.

I also wrote a command line utility SetVersion.exe utility that updates the version number on an AsssemblyInfo.cs or .vb file. The source for this is published as SetVersion on the MSDN Code Gallery.

So without further ado this is the MSBuild project file that performs the tasks.

<Project xmlns="" DefaultTargets="Build">
  <Target Name="Build">
    <Message Text="##Building version: $(Version)" Importance="high"/>
    <Message Text="##Cleaning folder..." Importance="high"/>
    <Exec Command="md $(BuildFolder)"/>
    <Message Text="##Getting latest version" Importance="high"/>
    <Exec Command="$(CodePlexClient) checkout $(CodePlexProjectName)" WorkingDirectory="$(BuildFolder)"/>
    <Message Text="##Updating build number $(SetVersion) $(BuildFolder)$(ProjectFolder)AssemblyVersionInfo.vb $(Version)" Importance="high"/>
    <Exec Command="$(SetVersion) $(BuildFolder)$(ProjectFolder)AssemblyVersionInfo.vb $(Version)"/>
    <Message Text="##Building" Importance="high"/>
    <MSBuild Projects="$(BuildFolder)$(BuildProject)" Targets="Publish" Properties="Configuration=Release;ApplicationVersion=$(Version)" />
    <Message Text="##Commiting version change" Importance="high"/>
    <Exec Command="$(CodePlexClient) commit /username $(CodePlexUser) /password $(CodePlexPassword) /message ---Automated-Build---$(Version)" WorkingDirectory="$(BuildFolder)"/>
    <Message Text="##Publishing" Importance="high"/>
    <Exec Command="rd $(IISPublishFolder) /s /q"/>
    <Exec Command="xcopy $(BuildFolder)$(BuildPublishFolder)\*.* $(IISPublishFolder) /e /i /y"/>
    <Exec Command="xcopy $(IISPublishFolder)..\default.htm $(IISPublishFolder)"/>

Although I’ve worked with MSBuild files in the past this was the very first time I wrote one so a few things to remember. Items defined in the <PropertGroup> node are like declaring variables. You can then use them anywhere in your script in this format $(VariableName).

What’s even better is that you can override the default values you provide in the build file with values from the command line like. For example to force a particular version number I can peform the build like this:

MSBuild ReleaseBuild.proj /p:Version=

When getting the latest version I opted to create a new folder for each build and pull the files into that folder. This way I didn’t have to worry about cleaning the bin folders. Every new build would start from an empty folder.

In my case rather than building the solution file I opted to build just the Client project since that would compile all the dependant projects. The key part that helped me create the necessary files for the ClickOnce publishing was the Targets=”Publish” parameter, that along with the ability to set the ClickOnce version using the properties provided an elegant solution for the tricky problem of keeping the AssemblyVersion and the ClickOnce application version in sync.

<MSBuild Projects="$(BuildFolder)$(BuildProject)" Targets="Publish" Properties="Configuration=Release;ApplicationVersion=$(Version)" />

I use CruiseControl to kick off the build process as well as drive the version numbering. CruiseControl is not absolutely necessary though, as the build file can be run from the command line, as long as a version number is specified.

I’ve packaged the build file along with the SetVersion.exe, cpc.exe (codeplex client) and the ccnet.config for download here.

Automate Build for a ClickOnce Application Hosted on CodePlex using MSBuild

WCF Performance Optimization Tips

I wound up work on my last project and thought of sharing some performance challenges we faced when the product went live.

Keep in mind though that optimization options heavily rely on your application design and its usage scenarios.

Usage Scenario

The usage scenario for which the following optimizations worked are as follows. The WCF services are hosted under IIS and currently only serve requests that come from the desktop client application through the intranet. Roughly 300 instances of the client application will be used concurrently.

Long running calls
The application design used the BackgroundWorker when making calls to the server but the actual WCF call was synchronous. Synchronous calls work well in most scenarios but when your service performs a long running task (>1 sec) it blocks other clients from connecting to the server. Asynchronous calls make better sense in this scenario.
Ref: Synchronous and Asynchronous Operations

When designing your application pick the binding carefully as this also affects performance. The WCF services were initially designed to use WSHttpBinding. This binding though affects performance especially when options such as security, reliable sessions and transaction flow are enabled.

As part of the performance tuning we switched to using BasicHttpBinding as none of the WS features were actually being used by the application. This dramatically improved performance because we cut down on all the acknowledgements.


Default WSHttpBinding
with Reliable Session Enabled (9 messages)
BasicHttpBinding (2 messages)
WsHttpBinding-Messages BasicBinding-Messages


The security we lost when switching over to BasicHttpBinding will be enforced at the network level by locking down the machines that are allowed to make calls to the service.

In our case we could have squeezed out more performance if we had used NetTcpBinding but that would have required IIS7 and WAS.

-    WCF Binding Comparison
-    BasicHttpBinding compared to WSHttpBinding at SOAP packet level [Note: Although this author recommends WS over Basic, Microsoft specifies that the secure and reliable sessions be disabled for Load Balanced environments which basically brings it down to Basic].
-    Load Balancing

Service Model Throttling
The service throttling parameters are another key element to look at when performance tuning services. The name is a little misleading though as it tends to imply that you want to throttle your service when in fact these are the default settings that the Microsoft engineers have put in place to prevent DOS attacks against your service.

In our case due to the nature of our application usage these settings caused the server to queue new requests once the default throttling levels of 10 concurrent sessions were reached. What effectively happened was that once long running queries were being processed other requests started getting queued up even though the server memory and processor usage were very low.

The resolution for this was to increase the default values for these settings (shown below) to a few thousand.

    <behavior name="DefaultThrottlingBehavior"> 
      <serviceThrottling maxConcurrentCalls="16" 
                         maxConcurrentInstances="[Int32.MaxValue]" /> 


-    <serviceThrottling>

-    Using ServiceThrottlingBehavior to Control WCF Service Performance

General guidelines when tuning performance


When tasked with tuning for performance the first requirement is to establish benchmarks on the current service levels and the expected service level once the tuning is completed.

Identify the bottleneck

The next key point is to identify the area that is causing the bottleneck. For the WCF services we tracked the time taken on the client side against the actual execution of the web service to eliminate the network being the bottleneck.

We worked backwards from the database call to ensure that they completed within the specified time.

Having your application instrumented is a key part of the initial design. The Enterprise Library provides instrumentation and open source tools such as log4net are lightweight and effective as well.

Replicate in your dev environment

Effectively testing out any tuning options can only be done if you can repro the issue in your development environment. The built-in load tester in Visual Studio will be a key part of your load testing armoury.

Code Profiling

If the bottleneck points to your code, code profiling tools will help your isolate the problem areas. At the time of this writing Red Gate ANTS Profiler and JetBrains dotTrace are capable solutions. The code profiler built into Visual Studio 2008 is not as effective as these tools.

Finally a shout-out to WCF MVP Buddhike who saved my day by quickly pointing me towards the binding and security modes as the perf culprits.

WCF Performance Optimization Tips


Silverlight  2.0 just went live. If you are a .NET developer building ASP.NET or WinForms/WPF applications this is a HUGE deal. Your .NET code can now run within a browser and across platforms (including Mac and on Linux using Moonlight) without requiring the .NET framework installed.

I have never spent much time learning AJAX but I see XAML/WPF basing used heavily in the future. When Silverlight 1.0 was first released I was excited at the prospect of re-using WPF knowledge to build web applications but was sorely disappointed with the lack of tooling and controls. Fast forward today and you have rich tooling support in Visual Studio a number of control (including a grid view and date picker) plus more controls being released by the Client Controls team.

Start learning Silverlight today your going to need it soon. Goodbye AJAX I will avoid you whenever I can.

To get started on Silverlight see the great ScottGu.