Setting up Cruise Control .NET 1.5/1.6 on Windows 7 + IIS7

I have been setting up a new continuous integration system on my laptop for some of my personal projects and thought it would be a good time to upgrade to Cruise Control 1.5. I came across some issues during the setup so I have put up my notes on the process in case anyone else has the same issues.
My Development Environment
Windows 7 (64-bit)
IIS 7.5
Cruise Control 1.6
Nant 0.86, Nant 0.91-alpha2
Visual Studio 2008, Visual Studio 2010
Installation Steps
  1. Download the installation package from
    • The release build of version 1.5 is available here on Source Forge.
    • The nightly build for version 1.6 is available here on CCNet Live.
  2. Run the installer. This will copy the files you need and create the IIS site/virtual directories needed to access Cruise Control .NET from your browser.
  3. Open your Internet Information Services (IIS) Manager (Start -> Run -> inetmgr )
  4. Create a new website point the site to <INSTALL PATH>webdashboard.
  5. Change the bindings for the new site to a unique port. ( I use port 90 and the CCNET is then accessed via http://localhost:90)
  6. Open the application pool created for this site and change the ‘Managed pipeline mode’ to ‘Integrated’.
  7. Open the services manager (Start -> Run -> services.msc) and start the Cruise Control .NET service.

Security& Permissions Issues

The default installation may cause issues due to permissions required to create folder (there are folders created on the fly for each CCNET project). It is best practice to have the CruiseControl.NET service running under a service account with proper permissions in the <INSTALL PATH>server and <INSTALL PATH>webdashboard  directories and subdirectories. The service account needs enough permissions to create new folders and files within the .server folder.


The new version of Cruise Control .NET has an admin dashboard that allows you to manage the plugins to display on the report pages. To enable the login, you need to modify /webdashboard/dashboard.config and add a password for the <administrationPlugin /> element.

As you install and uninstall the plugins, click the View Log button that appears next to the “Package has been installed” message to view the log of the installation. If there were any complications with the installation (usually permissions related), this log is your best source of information).

Visual Studio 2010 Unit Tests

The Visual Studio 2010 unit test results file has changed slightly from 2008. CCNET 1.6 addresses this issue.

jquery, ajax, and .NET Web Services

Recently, I have been working on a few projects that require an ajax friendly life cycle for an ASP.NET web application. Much of the work I did is based on Rick Strahl’s post:

Working on top of what I learned from this article, I decided to leverage the rich capabilities of .NET’s Web UI components as part of my ajax implementation using HTML injection. I used jquery to bind a standard button to make a call to my Web Service method.

The service created and populated a standard GridView object. The service would then render that object and return the HTML that was generated. This HTML, once returned by the service call, would be injected into a DIV tag that served as the container for the results table.

My initial implementation is a naive solution that renders full HTML on the server side and passes that back to the client-side. My ASP.NET page already has a script manager so I added a reference to my web service (simple .asmx in this scenario).

My service defines a method Foo:

namespace Client.Project.Services
/// Summary description for ConceptServices
[WebService(Namespace = “”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1, Name = “MyBinding”)]
public class ConceptServices : System.Web.Services.WebService
public String Foo()
return “Hello World!”;

To make a call to this method via client-side javascript, simple use the fully qualified name for the method:
Client.Project.Services.Foo( successMethod, failureMethod )
Assuming Foo is overloaded to take in parameters, you would pass in those parameters first:

var i = 3
var s = “bar”
Client.Project.Services.Foo( i, s, successMethod, failureMethod );
function successMethod( o ){
//o is the value returned by the web service call

Continuous Integration with Cruise Control, .NET (C#, WPF, ASP.NET) Projects, and NAnt

UPDATE: NAnt 0.91 Alpha 2 has been released with support for .NET 4. Download it here.
UPDATE: CruiseControl.NET 1.5 (Final) has been released and is available here.
UPDATE CruiseControl.NET 1.5 RC1 has been released and is available here.

My Cruise Control .NET implementation consists of numerous development projects each with multiple different Cruise Control .NET projects associated with it (one per environment per branch). In order to make the projects more maintainable, I have created a separate configuration file for each development project. Defining variables and separating ccnet.config configuration file into smaller files allows for easier maintenance of each project over their lifetimes.

Defining and using variables

Variables can be defined using the following format

<cb:define KEY=”VALUE” />

To reference that variable later in the configuration file, simply use $(KEY)

Check out the Cruise Control .NET website for complete explanation of variables using the pre-processor.

Separating the configuration files

<!DOCTYPE cruisecontrol [
<!ENTITY PROJECT_NAME SYSTEM “file:project.xml“>
<cruisecontrol xmlns:cb=”urn:ccnet.config.builder”>

project.xml would, then, contain the regular xml configuration for a Cruise Control .NET project:

<?xml version=”1.0″ encoding=”utf-8″?>
<project name=”My Project” category=”A Category”>
<intervalTrigger seconds=”900″ buildCondition=”IfModificationExists” />
<scheduleTrigger time=”04:00″ buildCondition=”ForceBuild” />
<labeller type=”svnRevisionLabeller”>
<pattern>Version {major}.{minor}.{build}.{revision}</pattern>
<sourcecontrol type=”svn”>
<cb:SvnOptions />
<xmllogger />
<cb:include href=”EmailConfig.xml”/>

On caveat with this idea is that changes to the separate configuration files are not recognized until the cruise control is restarted by either restarting the service or modifying the ccnet.config file.

Building and Deploying ASP.NET Web Applications

The NAnt target below is a full parameterized call to MsBuild.exe to compile any solution. ThoughtWorks.CruiseControl.MsBuild.dll provides an MSBuild logger that allows Cruise Control .NET to report the bulid output.

<target name=”build”>
<exec program=”${MSBuildPath}”>
<arg line='”${SolutionFile}”‘ />
<arg line=”/property:Configuration=${SolutionConfiguration}” />
<arg value=”/target:Rebuild” />
<arg value=”/verbosity:normal” />
<arg value=”/nologo” />
<arg line=’/logger:”C:Program FilesCruiseControl.NETserverThoughtWorks.CruiseControl.MsBuild.dll”‘/>


MSBuildPath – The path to the MsBuild executable.

For .NET Framework versions 2.0 and 3.5  on a 32-bit Windows OS, use C:WINDOWSMicrosoft.NETFrameworkv2.0.50727MsBuild.exe
For .NET Framework version 4.0, use C:WINDOWSMicrosoft.NETFrameworkv4.0.30319MsBuild.exe

SolutionFile – The relative path from the build file to the solution file. Fully qualified paths are also allowed.

SolutionConfiguration – “Release” or “Debug”.

I have been working on a website to aggregate funny technology related content across the internet. So far, I have been able to integrate pictures, YouTube videos, and some RSS content from fmylife and clientcopia

I have created the site using ASP.NET and SQL Server. I made this decision solely because I use Microsoft’s platform every day for my professional work.

Picture Uploads and Thumbnails

The pictures page ( allows visitors to add their own pictures. Upon uploading a picture, a thumbnail is also generate for that picture. The code below shows how to create a thumbnail of an uploaded image.

public System.Drawing.Image CreateThumbnail(System.Drawing.Image original, int width, int height)
return original.GetThumbnailImage(width, height, null, new IntPtr());

Ajax using jquery + .NET Web Services

Recently, I have also been introducing some new ajax functionality using jquery and .NET web services. This combination has allowed me to easily introduce a “preview” feature for uploading images and YouTube videos.

Content Management

Youtube Videos

The site is being updated to use the Youtube play list as the content manager for the videos page. Comments and ratings will be retrieved for the detail page and visitors to can add their own comments and ratings.

Performance and Load Testing with WebLoad

Recently, I had to perform a load test on our new project. We are using WebLoad to test the performance at different levels of load to see how it holds up. While WebLoad offers its own set of analytics, I am also using perfmon to see how each tier is performing under the stress.

I originally planned on using WebLoad 8.4 for the performance testing but have decided to stick with version 8.1. The free license for 8.4 limits you to 10 virtual users (the load size) where as V8.1 does not have any limitation.

WebLoad 8.1 can be downloaded here.

Perfmon Counters

The following counters will give the most pertinent results.

  • Requests Queued
  • Requests Current
  • Request Execution Time (lower is better)
  • Request Wait Time (lower is better)
  • Requests Rejected (lower is better, is best)


  • Context Switches / sec


  • Pages / sec
  • Available Bytes
  • Committed Bytes


  • % Processor Time
  • Active Server Pages
  • Request Wait Time
  • Requests Queued

Web Service

  • Current Connections
  • Bytes Send / sec
  • Connection Attempts / sec
  • Current Blocked Async I/O Requests
  • Current Blocked bandwidth bytes

Adventures in WCF (Windows Communication Foundation)

My latest project at work has me working with WCF for the first time and it has been an interesting experience. Over the next few weeks, I will be discussing configuration, debugging, and deployment of the WCF service and connecting to it.

Microsoft provides a few tools that can help debug your WCF services.

Error Handling

Typically, I add Global.asax to a web application in ASP.NET and use the Application_Error event to handle any uncaught exceptions.

protected void Application_Error(object sender, EventArgs e)
//Insert your application’s exception logging here

This doesn’t work (still looking into why) for WCF services, even when hosted on IIS. A good work around is to wrap each service method with a try…catch block and calling the exception logger in the catch block.

public Object MyWcfWrapperMethod( int i )
//Call the method being exposed by WCF
catch( Exception e ){
//Log the exception
//do your clean up here


Unit tests are especially helpful (aren’t they always?) in the development of your WCF services as messages from errror and exceptions can (and will) be hidden by subsequent errors. An invalid parameter to a stored procedure call can result in a high level System.ServiceModel.CommunicationObjectFaultedException.