Owen Emmett Jensen 9/29/2009

I would like to officially welcome Owen Emmett Jensen into the world!

IMG_0893

Microsoft pushed MVC to Beta!

Tonight microsoft has officially pushed ASP.NET MVC to Beta status.

Over the next few days I’ll be converting my CRM codebase to the new beta.

I’ll keep everyone posted on what has changed.

Apple…Stop shooting yourself in the face!

“The shortest straw has been pulled for you”

Just when you thought Apple couldn’t mismanage it’s App Store any more, they smother the release of a book educating developers on how to use their SDK.

You can’t make it up…

Developers are jumping ship by the hundreds to the new open Android platform that promises to give them much more control.

New Blog Theme!

I’ve decided to update WordPress and also change themes.

WOOHOO! Visual Studio 2008 is now being downloaded.

MSDN Released Visual Studio 2008 RTM to all MSDN Subscribers. I’m downloading the 3.1GB iso right now.

I’ll give a mini-review after i’ve had time to play with it over the Thanksgiving holiday.

Output parameters and dynamic sql

I came across something new for the first time today. Dynamic SQL with output parameters.

Here is how you do it in MSSQL.

DECLARE @totals INT
EXEC sp_executesql N’SELECT @totalCount = count(*) from sysobjects’, N’@totalCount INT OUTPUT’, @totals OUTPUT
print ‘Totals: ‘ + convert(varchar,@totals)

Visual Studio 2008 will be released in November.

Well you know you are an extreme geek when you are excited for a new release of an IDE.

I’m really looking forward to the integrated AJAX tools and the built in MVC framework.

http://www.vnunet.com/vnunet/news/2202822/microsoft-sets-date-fro-visual

ASP.NET 2.0 Hot Tips and Tricks

Dan Wahlin has posted an awesome group of ASP.NET Tips and Tricks that were introduced with the ASP.NET 2.0 Framework.  It seems like every month I find another hidden gem in Microsoft’s Framework.

 1. Maintain the position of the scrollbar on postbacks:  In ASP.NET 1.1 it was a pain to maintain the position of the scrollbar when doing a postback operation.  This was especially true when you had a grid on the page and went to edit a specific row.  Instead of staying on the desired row, the page would reload and you’d be placed back at the top and have to scroll down.  In ASP.NET 2.0 you can simply add the MaintainScrollPostionOnPostBack attribute to the Page directive:

<%@ Page Language=”C#” MaintainScrollPositionOnPostback=”true” AutoEventWireup=”true” CodeFile=”…” Inherits=”…” %>

2.  Set the default focus to a control when the page loads:  This is another extremely simple thing that can be done without resorting to writing JavaScript.  If you only have a single textbox (or two) on a page why should the user have to click in the textbox to start typing?  Shouldn’t the cursor already be blinking in the textbox so they can type away?  Using the DefaultFocus property of the HtmlForm control you can easily do this.

<form id=”frm” DefaultFocus=”txtUserName” runat=”server”>
  …
</form>

3. Set the default button that is triggered when the user hits the enter key:  This was a major pain point in ASP.NET 1.1 and required some JavaScript to be written to ensure that when the user hit the enter key that the appropriate button on the form triggered a “click” event on the server-side.  Fortunately, you can now use the HtmlForm control’s DefaultButton property to set which button should be clicked when the user hits enter.  This property is also available on the Panel control in cases where different buttons should be triggered as a user moves into different Panels on a page.

<form id=”frm” DefaultButton=”btnSubmit” runat=”server”>
  …
</form>

4. Locate nested controls easily: Finding controls within a Page’s control hierarchy can be painful but if you know how the controls are nested you can use the lesser known “$” shortcut to find controls without having to write recursive code.  If you’re looking for a great way to recursively find a control (in cases where you don’t know the exact control nesting) check out my good buddy Michael Palermo’s blog entry. The following example shows how to use the DefaultFocus property to set the focus on a textbox that is nested inside of a FormView control.  Notice that the “$” is used to delimit the nesting:

<form id=”form1″ runat=”server” DefaultFocus=”formVw$txtName”>
<div>
<asp:FormView ID=”formVw” runat=”server”>
<ItemTemplate>
Name: 
<asp:TextBox ID=”txtName” runat=”server” 
Text=’<%# Eval(“FirstName”) + ” ” + Eval(“LastName”) %>’ />
</ItemTemplate>
</asp:FormView>
</div>
</form>

This little trick can also be used on the server-side when calling FindControl().  I blogged about this awhile back if you’d like more details.  Here’s an example:

TextBox tb = this.FindControl(“form1$formVw$txtName”) as TextBox;
if (tb != null)
{
//Access TextBox control
}

5. Strongly-typed access to cross-page postback controls:  This one is a little more involved than the others, but quite useful.  ASP.NET 2.0 introduced the concept of cross-page postbacks where one page could postback information to a page other than itself.  This is done by setting the PostBackUrl property of a button to the name of the page that the button should postback data to.  Normally, the posted data can be accessed by doing something like PreviousPage.FindControl(“ControlID”).  However, this requires a cast if you need to access properties of the target control in the previous page (which you normally need to do).  If you add a public property into the code-behind page that initiates the postback operation, you can access the property in a strongly-typed manner by adding the PreviousPageType directive into the target page of the postback.  That may sound a little confusing if you haven’t done it so let me explain a little more.

If you have a page called Default.aspx that exposes a public property that returns a Textbox that is defined in the page, the page that data is posted to (lets call it SearchResults.aspx) can access that property in a strongly-typed manner (no FindControl() call is necessary) by adding the PreviousPageType directive into the top of the page:

<%@ PreviousPageType VirtualPath=”Default.aspx” %>

By adding this directive, the code in SearchResults.aspx can access the TextBox defined in Default.aspx in a strongly-typed manner.  The following example assumes the property defined in Default.aspx is named SearchTextBox.

TextBox tb = PreviousPage.SearchTextBox;

This code obviously only works if the previous page is Default.aspx.  PreviousPageType also has a TypeName property as well where you could define a base type that one or more pages derive from to make this technique work with multiple pages.  You can learn more about PreviousPageType here.

6. Strongly-typed access to Master Pages controls: The PreviousPageType directive isn’t the only one that provides strongly-typed access to controls.  If you have public properties defined in a Master Page that you’d like to access in a strongly-typed manner you can add the MasterType directive into a page as shown next (note that the MasterType directive also allows a TypeName to be defined as with the PreviousPageType directive):

<%@ MasterType VirtualPath=”MasterPage.master” %>

You can then access properties in the target master page from a content page by writing code like the following:

this.Master.HeaderText = ”Label updated using MasterType directive with VirtualPath attribute.”;

You can find several other tips and tricks related to working with master pages including sharing master pages across IIS virtual directories at a previous blog post I wrote

7. Validation groups: You may have a page that has multiple controls and multiple buttons.  When one of the buttons is clicked you want specific validator controls to be evaluated rather than all of the validators defined on the page.  With ASP.NET 1.1 there wasn’t a great way to handle this without resorting to some hack code.  ASP.NET 2.0 adds a ValidationGroup property to all validator controls and buttons (Button, LinkButton, etc.) that easily solves the problem.  If you have a TextBox at the top of a page that has a RequiredFieldValidator next to it and a Button control, you can fire that one validator when the button is clicked by setting the ValidationGroup property on the button and on the RequiredFieldValidator to the same value.  Any other validators not in the defined ValidationGroup will be ignored when the button is clicked. Here’s an example:

<form id=”form1″ runat=”server”>
    Search Text: <asp:TextBox ID=”txtSearch” runat=”server” /> 
    <asp:RequiredFieldValidator ID=”valSearch” runat=”Server”
      ControlToValidate=”txtSearch” ValidationGroup=”SearchGroup” /> 
    <asp:Button ID=”btnSearch” runat=”server” Text=”Search”
ValidationGroup=”SearchGroup” />
    ….
    Other controls with validators and buttons defined here
</form>

8. Finding control/variable names while typing code:  This tip is a bit more related to VS.NET than to ASP.NET directly, but it’s definitely helpful for those of you who remember the first few characters of control variable name (or any variable for that matter) but can’t remember the complete name.  It also gives me the chance to mention two great downloads from Microsoft.  First the tip though.  After typing the first few characters of a control/variable name, hit CTRL + SPACEBAR and VS.NET will bring up a short list of matching items.  Definitely a lot easier than searching for the control/variable definition.  Thanks to Darryl for the tip.  For those who are interested, Microsoft made all of the VS.NET keyboard shortcuts available in a nice downloadable and printable guide.  Get the C# version here and the VB.NET version here.

Seven Ways to Make Money From Your CRM

Can a CRM (Customer Relationship Management) system really create profits for a company? A lot of people don’t think so – over the years the media has reported quite a few companies (both big and small) that have tossed a significant amount of dollars down the drain on these kind of systems. But there have been plenty of successes too. In fact, during the 12 years we’ve been selling and implementing CRM products like GoldMine and Microsoft CRM we’ve seen some penny pinching business owners really get a lot of bang for their bucks. Here’s how.

The Lonely Old Quote: Tyler, who runs a parts distribution company had a big problem: one of out of every ten quotes his salesmen sent were never followed up! Sure, some of these opportunities may have been lost to others, but Tyler wondered just how many of these quotes could’ve turned into a sale if someone would’ve just called the customer. The problem? He had no system to track his quotes! Tyler made changes – he purchased a simple CRM system and made sure that each quote was tagged with a follow-up call and alerts to the sales staff when they were due. He also built in an alarm for his sales manager in case a salesperson was ignoring his follow up calls. Within a few weeks Tyler could see the difference. Every quote was now pursued with either a phone call or email.

Opportunities that could’ve slipped through the cracks were now addressed. Sales increased.

The Bright Side Of A Lost Sale: Don, a penny pinching manager at a consulting firm, actually thinks there’s a bright side to a lost sale. “Because of our CRM system,” he says. “We can track every time a sale does not go our way.” Sometimes a competing product beat them. Other times a customer decides not to do anything at all. Whatever the reason, Don’s company tracks the history and every three months runs a Lost Sales Report and does a post mortem. It’s never pretty. It’s oftentimes frustrating. “But it’s ALWAYS educational,” Don continues. “Armed with where we screwing up, we can adjust and win back more dollars going forward.” And he wouldn’t be able to do it without his CRM system.

Too Few Sales Calls, Too Many Donuts: Jim, another penny pinching manager who works at a large cable company was often confronted by sales guys asking for more money. Jim always turns to his CRM system and says, “Well, let’s take a look at the old batting average”. Here, Jim can see how many quotes a salesperson put out vs. what he closed. “Now, now,” Jim chuckles. “What can we do to increase this percentage so YOU get more money.” Jim tracks his sales people’s calls and appointments and looks at their productivity. “Now why did you spend so much time with this little prospect, when you could’ve been spending more time with that bigger fish?” A good CRM system helps the penny pincher squeeze the most efficiency from his sales team.

Don’t You Hate Looking Like A Dope? The other day Harry, a sales rep for a software company, called one of his customers to tell them all about the great features coming in the software’s up and coming new release. He wasn’t prepared for the response he got. “New release?” his customer yelled. “How about getting the OLD release working first!” Because Harry’s company didn’t have a CRM system he had no idea that his service group was working on a problem with this customer. His call did nothing more than enflame emotions, rather than creating good will. More dopey moments like that and Harry could watch his sales disappear. A good CRM system ensures that everyone in the company knows everything that’s going on with your customers. And your prospects, vendors and other parties too. This way no one looks like a dope when representing your business.

Too Few Service Calls, Too Many Donuts: It’s not just penny pinchers who recognize the value of time as well as money. But good penny pinchers do something about it. Do you have a system that tracks how employees spend their time on issues, problems, breaks and other customer complaints? Is service time being wasted? Are there service issues that aren’t being addressed? How come this one part has so many problems? Should we keep doing business with that customer who calls us so much? Can you get an alert when certain issues are breached? Using CRM software to track how productive your service group is will save a lot of pennies in the long run.

Fun And Games With Duplicate Data: For goodness sake, just how many places do I need to keep the same information? Sandy kept asking herself this question. A typical penny pincher, she hated the fact that customer information was entered in her website, in her accounting system, in her email system, in spreadsheets and other databases. “Enough!” she yelled. She got a CRM system. She designed one web form to capture the customer data and the CRM system took care of that. The same data was sent automatically to other systems. Accounting and inventory information stayed in her financial system, but her CRM system was able to be configured to view that data. Enter it once, make it available elsewhere. Buying a good CRM system? A few thousand bucks. Using it to eliminate wasted time and incorrect data entry? Priceless!

Getting the word out – mass communications: Alexis knew that the more customers she could reach, the more opportunities she could create and even more pennies would drop into her bank account. So she configured her www.marksgroup.net CRM system to send out automatic emails to customers who hadn’t ordered in a while and to customers who ordered a product in the past who may be interested in an accessory or similar product. She produced with her system direct mail pieces each day announcing specials. She created a newsletter to keep her customers informed about new developments. Her CRM software sent out faxes to groups of customers who gave her permission to alert them to new incentives. She scheduled groups of telemarketing calls to be made by high school kids in the evening. Alexis is no mass marketer but she’s certainly a great penny pincher. And her bottom line shows the results! 

Source: http://www.smartbiz.com

By:  Gene Marks

Tutorial on NAnt: How to install and configure

NAnt is a free .NET build tool based on Ant (a build tool for Java). NAnt, like Ant, is similar to Make in that it is used to generate output from your source files. But where Ant is Java-centric, NAnt is .NET-centric. NAnt has built-in support for compiling C#, VB.NET, and J# files and can use Visual Studio .NET solution files to do builds. NANt also has built-in support for NUnit and NDoc (.NET version of JUnit and JDoc, respectively).

NAnt is a useful tool for automating the build process. The build process can include tasks such as compiling source code and resource files into assemblies, running unit tests, configuring build-specific settings, and so on. The benefit of tools like NAnt is that they help automate the build process by providing enough power and flexibility to highly customize build actions for specific applications. This article provides an overview of NAnt, including its purpose, how to download and install NAnt, using NAnt, and other NAnt essentials. Read on to learn more!

What is a this thing you call Build Tool?

A “build tool” is a tool that you use to build your source code and resources files into assemblies.  We use build tools everyday in development.  Here are some tasks that are performed during the “entire” build process:

  • Get latest source code from source code control (SVN/VSS/CVS).
  • Configure the build (put files in specific folders based on build number).
  • Compile the code
  • Run Unit Tests
  • Create Documentation from the source code comments
  • Include non-code output files in the output of the build (images, database files, config files, etc..)
  • Package the output for deployment

NAnt and other build tools allow you to automate some or all of these steps.  You can configure the build tool to kick off the processes and automate a lot of work that is usual manual and tedious.

OK So what does NAnt do?  Why is it the best?

NAnt is different.  Instead of a model where it is extended with shell-based commands, NAnt is extended using task classes.  Instead of writing shell commands, the configuration files are XML-based, calling out a target tree where various tasks get executed.  Each task is run by an object that implements a particular Task interface.

Granted, this removes some of the expressive power that is inherent in being able to construct a shell command such as ‘find . -name foo -exec rm {}’, but it gives you the ability to be cross-platform – to work anywhere and everywhere. And hey, if you really need to execute a shell command, NAnt has an <exec> task that allows different commands to be executed based on the OS it is executing on.

What is Required?

The system requirements are pretty obvious and simple.  To use Nant you need one of the following CLR’s:

  • Microsoft .NET Framework 1.0
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 2.0
  • Mono 1.x

Note: Additional requirements may apply to individual tasks.

NAnt uses a number of open source third party libraries.  Recent versions are included with NAnt distribution and no extra work is required to install them.  More information on these libraries are available at:

> NUnit – Required for unit testing

> NDoc – Required for documentation generation

> SharpZipLib – Required for the zip and unzip tasks

OK So it sounds like I need it, How do I install it?

NAnt is available in either a source or binary distribution. The binary distribution is all you need to use NAnt to build your projects, including creating your own custom tasks, types and functions.

If you are upgrading NAnt from a previous version, you must never install over the top of your previous installation. Delete or rename the existing installation directory before installing the new version of NAnt.

Installing from binaries

  1. Download the binary distribution archive. Either ant-bin.zip or nant-bin.tar.gz will work, the contents of each archive are the same.
  2. Remove any previous versions of NAnt you may have installed.
  3. Extract the contents of the archive to the location you wish to install NAnt (eg: C:\Program Files\NAnt in windows, or /usr/local/nant in Linux)
  4. Depending on your environment, create a wrapper script to run NAnt:
    Run NAnt using Microsoft.NET
    • Create a file called nant.bat in a directory that is included in the PATH system environment variable. (eg. C:\WINDOWS).
    • Add the following to nant.bat:
      @echo off
      "C:\Program Files\NAnt\bin\NAnt.exe" %*
                              
    Run NAnt using Mono
    • Windows
      • Create a file called nant.bat in a directory that is included in the PATH system environment variable. (eg. C:\WINDOWS).
      • Add the following to nant.bat:
        @echo off
        mono "C:\Program Files\NAnt\bin\NAnt.exe" %*
                                        
    • Linux / Cygwin
      • Create a file called nant in a suitable location in your filesystem (eg. /usr/local/bin).
      • Add the following to nant:
        #!/bin/sh
        exec mono /usr/local/nant/bin/NAnt.exe "$@"
                                
      • Ensure nant has permission to execute, eg:
        chmod a+x /usr/local/bin/nant
                                
  5. Open a new command prompt (shell) and type nant -help. If successful, you should see a usage message displaying available command line options.
  6. (optional) Download and install NAnt-contrib or other third party extensions to NAnt.

Installing from source

  1. Download the source distribution archive. Either nant-src.zip or nant-src.tar.gz will work, the contents of each archive are the same.
  2. Remove any previous versions of NAnt you may have installed.
  3. Extract the contents of the archive to a temporary location. This should not be the location you wish to install NAnt to.
  4. Open a command prompt and change into the folder you extracted the archive to.
  5. Depending on your environment, build the NAnt distribution:
    Install NAnt using Microsoft .NET
    • GNU Make

      make install MONO= MCS=csc prefix=<i>installation-path</i>

      eg. make install MONO= MCS=csc prefix="C:\Program Files"

    • NMake

      nmake -f Makefile.nmake install prefix=<i>installation-path</i>

      eg. nmake -f Makefile.nmake install prefix="C:\Program Files"

    Install NAnt using Mono
    • GNU Make

      make install prefix=<i>installation-path</i>

      eg. make install prefix="C:\Program Files"

    • NMake

      nmake -f Makefile.nmake install MONO=mono CSC=mcs prefix=<i>installation-path</i>

      eg. nmake -f Makefile.nmake install MONO=mono CSC=mcs prefix=/usr/local/

    This will first build a bootstrap version of NAnt, and then use that to build and install the full version to <i>installation-path</i>/NAnt.

  6. Follow the instructions as for a binary release from step 5.

 

Installed….CHECK!  Now how does it work?

NAnt is a command-line application that acts on build files that you write in XML. Each build file contains one project and any number of properties and targets. A property is a variable and a target is a set of tasks. An example is worth a thousand words, so here is Hello World as an NAnt build file:

<?xml version="1.0"?>
<project name="Hello World" default="hello">
    <property name="hello.string" value="Hello World" />
    <target name="hello" description="Echoes 'Hello World'">
        <echo message="${hello.string}" />
    </target>
</project>

NAnt looks for build files in the current directory with a .build extension. If there is more than one build file in the current directory, NAnt looks for one named default.build and, if present, uses it. You can explicitly specify the build file to use with the -buildfile:<i>&lt;filename&gt;</i> command line argument.

All NAnt build files require one (and only one) &lt;project&gt; tag. In the ‘Hello World’ example, the &lt;project&gt; tag contains the default argument. The default argument specifies which target NAnt is to execute by default. In this case, NAnt will execute the hello target by default.

The ‘Hello World’ example defines one property and one target. The property is named hello.string and its value is ‘Hello World’. (Properties don’t have to be named with periods, but often are in NAnt build files). The ‘Hello World’ example’s one target is named hello and it contains one task. The &lt;echo&gt; task echoes the string indicated by the message argument. The syntax ${hello.string} may be confusing at first, but this syntax is simply telling NAnt to substitute the value of the hello.string property in its place.

Assuming you named the ‘Hello World’ example build file default.build, you would simply enter nant at the command line to build it:

C:\>nant

(You could specify the ‘hello’ target on the command line (C:\&gt; nant hello), but since this is the default target, this is unnecessary.)

How about a More Practical Example?

Here’s a build file (based on the excellent article by Giuseppe Greco, Building Projects With NAnt) that compiles a HelloWorld.cs source file. In addition to the build target, it includes a debug target. This enables you to specify whether or not this build should including debugging information:

&lt;?xml version="1.0"?&gt;<br>&lt;project name="HelloWorld" default="build"&gt;<br>&nbsp;&nbsp;&lt;property name="project.version" value="1.0" /&gt;<br>&nbsp;&nbsp;&lt;property name="project.config" value="release" /&gt;<br>&nbsp;&nbsp;&lt;target name="init"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;call target="${project.config}" /&gt;<br>&nbsp;&nbsp;&lt;/target&gt;<br>&nbsp;&nbsp;&lt;target name="debug"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="project.config" value="debug" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="build.debug" value="true" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="basedir.suffix" value="-debug" /&gt;<br>&nbsp;&nbsp;&lt;/target&gt;<br>&nbsp;&nbsp;&lt;target name="release"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="project.config" value="release" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="build.debug" value="false" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="basedir.suffix" value="-release" /&gt;<br>&nbsp;&nbsp;&lt;/target&gt;<br>&nbsp;&nbsp;&lt;target name="build" depends="init" description="compiles the source code"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="build.dir" value="${nant.project.basedir}/${nant.project.name}_${project.version}${basedir.suffix}"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;mkdir dir="${build.dir}" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;csc target="exe" output="${build.dir}/HelloWorld.exe" debug="${build.debug}"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;sources&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;includes name="HelloWorld.cs" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/sources&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/csc&gt;<br>&nbsp;&nbsp;&lt;/target&gt;<br>&lt;/project&gt;

Things to notice about this build file:

  • There are targets for debug and release. You include these targets on the command line to specify the type of build configuration. Notice that release is the default configuration.
  • The build target has a depends argument. This tells NAnt to make sure the init target is up to date before calling the build target.
  • The init target calls another target explicitly. In this case, it calls either the release or debug target.
  • The output is put into a directory that is named with the project version and configuration (1.0_HelloWorld-release or 1.0_HelloWorld-debug)

Assuming you have a valid HelloWord.cs file in the same directory as the build file, you can build the release version of this project just by entering nant at the command-line. This is equivalent to entering nant release build, but because project.config is set to release by default and the default target is build, this isn’t necessary.

If you want to do a debug version of this project, use the following command: nant debug build. Note that you must specify the build target in this case. If you specify any targets on the command line, NAnt ignores the default target. If you just entered nant debug, NAnt would have executed the debug target and then exited. If you notice that the debug target is called twice when doing a debug build, you can move to the head of the class. It is called first because you specify it on the command line and a second time by the init target. This is not as efficient as it could be, but I left it this way for simplicity.

Obviously we are just scratching the surface of what NAnt can do with the above example.

What is the Workflow of a Build Using NAnt?

Once you have your build file(s) written and tested, you will want to start using them for your builds. Performing a build with a build tool like NAnt usually involves these steps:

  1. Set a version property in your build file to the value for the current build (you could also pass this to NAnt on the command line)
  2. Get the latest source from source code control (if you do not have NAnt do this for you)
  3. Run NAnt with appropriate command line targets (debug build, for example)
  4. Wait for the build to complete (you can use NAnt’s &lt;mail&gt; task to have NAnt notify you by email when the build completes; this is useful for solutions that require especially long builds)
  5. Handle any build errors. NAnt will fail if it encounters any errors. If a file fails to compile, for example, NAnt will fail. You can configure some tasks to either fail or not fail on error. The &lt;copy&gt; task is an example.
  6. If the build succeeded, deploy the build output. (NAntContrib includes an &lt;msi&gt; task if you want to create .msi installation packages from NAnt.)

You can actually automate the NAnt build process using continuous integration tools like Draco.NET and CruiseControl. These tools monitor your source code and automatically perform builds when they detect changes.