<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Blog</title><link>http://www.26tp.com:80/blog</link><description>Blog</description><item><title>How to efficiently move and delete files on D-Link DNS-313 NAS Drive</title><link>http://www.26tp.com:80/blog/how-to-efficiently-move-and-delete-files-on-d-link-dns-313-nas-drive</link><description>&lt;p&gt;From time to time I have the need to delete or move a number of large files on my &lt;a href="http://www.dlink.com.au/products/?pid=DNS-313"&gt;DNS-313 SHARECENTER™ 1-BAY NETWORK STORAGE&lt;/a&gt; drive. Using Windows Explorer, or even Command Prompt, is slow as! A more efficient method is to &lt;strong&gt;telnet&lt;/strong&gt; into the NAS drive.&lt;/p&gt; &lt;h2&gt;Starting telnet service&lt;/h2&gt; &lt;p&gt;By default telnet is not available available on the DNS-313. To start the &lt;strong&gt;telnet&lt;/strong&gt; service go to http://&amp;lt;your dns-313 name or ip address&amp;gt;/web/telnetd.asp.&lt;/p&gt; &lt;p&gt;Note that the telnet service needs to be restarted after a rebooting DNS-313 drive.&lt;/p&gt; &lt;h2&gt;Connecting to DNS-313 with telnet&lt;/h2&gt; &lt;p&gt;Start telnet and enter the following command.&lt;/p&gt;&lt;pre class="prettyprint"&gt;open &amp;lt;your dns-313 name or ip address&amp;gt;&lt;/pre&gt;
&lt;p&gt;When prompted enter the login name of &lt;strong&gt;root&lt;/strong&gt; and password &lt;strong&gt;11111&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;At this point you should have the following screen:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.26tp.com/Media/Default/Windows-Live-Writer/How-to_11DC7/telnet-dns-313_4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="telnet-dns-313" border="0" alt="telnet-dns-313" src="http://www.26tp.com/Media/Default/Windows-Live-Writer/How-to_11DC7/telnet-dns-313_thumb_1.png" width="684" height="348"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enter the unlock code &lt;strong&gt;5784468&lt;/strong&gt; and now have a standard telnet connection.&lt;/p&gt;
&lt;p&gt;The operating system for DNS-313 is Linux. &lt;a href="http://www.yolinux.com/TUTORIALS/unix_for_dos_users.html"&gt;http://www.yolinux.com/TUTORIALS/unix_for_dos_users.html&lt;/a&gt; is good cheat sheet for the Windows/DOS users amongst us to get around this Linux box.&lt;/p&gt;
&lt;p&gt;The following command will take us to the data directory on the drive.&lt;/font&gt;&lt;/p&gt;&lt;pre class="prettyprint"&gt;cd /mnt/HD_a2&lt;/pre&gt;
&lt;h2&gt;Remove Folder&lt;/h2&gt;
&lt;p&gt;The following Linux command will remove a folder.&lt;/p&gt;&lt;pre class="prettyprint"&gt;rm –R &amp;lt;folder&amp;gt;&lt;/pre&gt;
&lt;p&gt;There is no progress indicator doing large removals; just an empty line. The # prompt will appear when the folder has been removed.&lt;/p&gt;
&lt;h2&gt;Move Folder or File&lt;/h2&gt;
&lt;p&gt;The following Linux command will move a folder or file.&lt;/p&gt;&lt;pre class="prettyprint"&gt;mv SOURCE DEST&lt;/pre&gt;</description><pubDate>Tue, 17 May 2011 11:43:05 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/how-to-efficiently-move-and-delete-files-on-d-link-dns-313-nas-drive</guid></item><item><title>Goodbye BlogEngine; Hello Orchard - How To</title><link>http://www.26tp.com:80/blog/goodbye-blogengine-hello-orchard-how-to</link><description>&lt;p&gt;My move from BlogEngine to Orchard was reasonably painless. That is except for the URL rewriting. Who ever invented RegEx should be shot.&lt;/p&gt;
&lt;p&gt;The two posts I found most help for the move were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a title="Walking Through the Orchard Part 1 - Setting up a Blog - John Papa" href="http://johnpapa.net/orchardpart1"&gt;Walking Through the Orchard Part 1 - Setting up a Blog - John Papa&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a title="Walking Through the Orchard Part 3 - BlogML Import and Rewrite Rules - John Papa" href="http://johnpapa.net/orchardpart3"&gt;Walking Through the Orchard Part 3 - BlogML Import and Rewrite Rules - John Papa&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To follow is a very short hand list of steps I took to replace BlogEngine with Orchard. Over time I will blog about each step in more detail.&lt;/p&gt;
&lt;h2&gt;Preparing for the move&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Spider the existing site 
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://home.snafu.de/tilman/xenulink.html"&gt;&lt;span color="#0066cc" style="color: #0066cc;"&gt;http://home.snafu.de/tilman/xenulink.html&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Export &amp;ndash; BlogML 
&lt;ul&gt;
&lt;li&gt;www.example.com/admin/Pages/Settings.aspx &lt;/li&gt;
&lt;li&gt;Bottom of page click Export button.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Download Site 
&lt;ul&gt;
&lt;li&gt;zip &lt;/li&gt;
&lt;li&gt;ftp &lt;/li&gt;
&lt;li&gt;unzip&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Delete Site 
&lt;ul&gt;
&lt;li&gt;Delete from IIS &lt;/li&gt;
&lt;li&gt;Reboot &lt;/li&gt;
&lt;li&gt;Delete folder&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Installing Orchard&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Run Microsoft Web Platform Installer &lt;/li&gt;
&lt;li&gt;Complete the Orchard setup page &lt;/li&gt;
&lt;li&gt;Unpublish the default home page and create temporary one. &lt;/li&gt;
&lt;li&gt;FTP google webmaster page &lt;/li&gt;
&lt;li&gt;Adjust maxRequestLength in Web.Config.  
&lt;ul&gt;
&lt;li&gt;Defaults to 4096. &lt;/li&gt;
&lt;li&gt;In hindsight zipping the file would probably get around this. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Create Blog &lt;/li&gt;
&lt;li&gt;Import BlogML module. &lt;/li&gt;
&lt;li&gt;Import blog  
&lt;ul&gt;
&lt;li&gt;Comments are not automatically approved. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reset maxRequestLength in Web.Config. &lt;/li&gt;
&lt;li&gt;Setup URL rewrite 
&lt;ul&gt;
&lt;li&gt;Install module &lt;/li&gt;
&lt;li&gt;Go to www.example.com/Admin/Settings/Index to enable and define rules.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Enable LiveWriter support 
&lt;ul&gt;
&lt;li&gt;www.example.com/Admin/Modules/Features &lt;/li&gt;
&lt;li&gt;In Content Publishing section enable Remove Blog Publishing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description><pubDate>Sun, 08 May 2011 23:07:23 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/goodbye-blogengine-hello-orchard-how-to</guid></item><item><title>Create Generic Classes</title><link>http://www.26tp.com:80/blog/Create-Generic-Classes</link><description>&lt;blockquote&gt;
&lt;p&gt;A generic type is a single programming element that adapts to perform the same functionality for a variety of data types. When you define a generic class or procedure, you do not have to define a separate version for each data type for which you might want to perform that functionality.&lt;/p&gt;
&lt;p&gt;Source: &lt;a href="http://msdn.microsoft.com/en-us/library/w256ka79.aspx"&gt;MSDN Generic Types in Visual Basic&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;No doubt you&amp;rsquo;ve already used generic classes list like List(Of T) but how do you create your own generic class? Lets take simply NumberRange example. The purpose of the class is to set a minimum and maximum value then test if a value is in this range. The following class does that for integers.&lt;/p&gt;
&lt;pre class="brush: vb;"&gt;''' &amp;lt;summary&amp;gt;
''' Allows a range to be set for and test if a value is between that range.
''' &amp;lt;/summary&amp;gt;
Public Class IntegerRangeWithoutGeneric

    Private mMinValue As Integer
    Private mMaxValue As Integer

    ''' &amp;lt;summary&amp;gt;
    ''' Initializes a new instance of the &amp;lt;see cref="IntegerRangeWithoutGeneric" /&amp;gt; class.
    ''' &amp;lt;/summary&amp;gt;
    Public Sub New()
    End Sub

    ''' &amp;lt;summary&amp;gt;
    ''' Initializes a new instance of the &amp;lt;see cref="IntegerRangeWithoutGeneric" /&amp;gt; class while setting &amp;lt;see cref="MinValue"/&amp;gt; and &amp;lt;see cref="MaxValue"/&amp;gt;.
    ''' &amp;lt;/summary&amp;gt;
    Public Sub New(ByVal minValue As Integer, ByVal maxValue As Integer)

        mMinValue = minValue
        mMaxValue = maxValue

    End Sub

    ''' &amp;lt;summary&amp;gt;
    ''' Returns True if &amp;lt;paramref name="value"/&amp;gt; is between &amp;lt;see cref="MinValue"/&amp;gt; and &amp;lt;see cref="MaxValue"/&amp;gt; inclusive.
    ''' &amp;lt;/summary&amp;gt;
    Public Function IsValid(ByVal value As Integer) As Boolean

        Return value &amp;gt;= mMinValue AndAlso value &amp;lt;= mMaxValue

    End Function

    ''' &amp;lt;summary&amp;gt;
    ''' Gets or sets the Minimum value for the range.
    ''' &amp;lt;/summary&amp;gt;
    Public Property MinValue() As Integer
        Get
            Return mMinValue
        End Get
        Set(ByVal value As Integer)
            mMinValue = value
        End Set
    End Property

    ''' &amp;lt;summary&amp;gt;
    ''' Gets or sets the Maximum value for the range.
    ''' &amp;lt;/summary&amp;gt;
    Public Property MaxValue() As Integer
        Get
            Return mMaxValue
        End Get
        Set(ByVal value As Integer)
            mMaxValue = value
        End Set
    End Property

End Class

&lt;/pre&gt;
&lt;p&gt;No doubt this class achieves what we want but now we need the same thing for testing number of type double. Sure we could copy and paste the code, do a search and replace of Integer for Double but you know that&amp;rsquo;s not the best way. So lets create a Generic class.&lt;/p&gt;
&lt;pre class="brush: vb;"&gt;Public Class NumberRange(Of T)

    Private mMinValue As T
    Private mMaxValue As T

    Public Sub New()
    End Sub

    Public Sub New(ByVal minValue As T, ByVal maxValue As T)

        mMinValue = minValue
        mMaxValue = maxValue

    End Sub

    Public Function IsValid(ByVal value As T) As Boolean

        Return value &amp;gt;= mMinValue AndAlso value &amp;lt;= mMaxValue

    End Function

    Public Property MinValue() As T
        Get
            Return mMinValue
        End Get
        Set(ByVal value As T)
            mMinValue = value
        End Set
    End Property

    Public Property MaxValue() As T
        Get
            Return mMaxValue
        End Get
        Set(ByVal value As T)
            mMaxValue = value
        End Set
    End Property

End Class
&lt;/pre&gt;
&lt;p&gt;To make the class generic the class deleclaration line was changed to NumberRange(Of T). The (Of T) tells the compilier when the class is created it must be initialised with the type we are going to test. For example:&lt;/p&gt;
&lt;pre class="brush: vb;"&gt;Dim integerTest As New NumberRange(Of Integer)(1, 10)Dim doubleTest As New NumberRange(Of Double)(0.1, 0.9)

If integerTest.IsValid(2) Then
...
End If

If doubleTest.IsValid(0.5) Then
...
End If
&lt;/pre&gt;
&lt;p&gt;Wouldn&amp;rsquo;t it be nice if it was quite that simple. Unfortunately with generic types the only recognised operator is equals (=) therefore for our IsValid method will not work. To get around this problem we will need to make the NumberRange class MustInherit.&lt;/p&gt;
&lt;pre class="brush: vb;"&gt;Public MustInherit Class NumberRange(Of T)

    Private mMinValue As T
    Private mMaxValue As T

    Public MustOverride Function IsValid(ByVal value As T) As Boolean
    Public Sub New()
    End Sub

    Public Sub New(ByVal minValue As T, ByVal maxValue As T)

        mMinValue = minValue
        mMaxValue = maxValue

    End Sub

    Public Property MinValue() As T
        Get
            Return mMinValue
        End Get
        Set(ByVal value As T)
            mMinValue = value
        End Set
    End Property

    Public Property MaxValue() As T
        Get
            Return mMaxValue
        End Get
        Set(ByVal value As T)
            mMaxValue = value
        End Set
    End Property

End Class
&lt;/pre&gt;
&lt;p&gt;Then for our IntegerRange class:&lt;/p&gt;
&lt;pre class="brush: vb;"&gt;Public Class IntegerRangeWithGeneric
    Inherits NumberRange(Of Integer)

    Public Sub New()
    End Sub

    Public Sub New(ByVal minValue As Integer, ByVal maxValue As Integer)
        MyBase.New(minValue, maxValue)
    End Sub

    Public Overrides Function IsValid(ByVal value As Integer) As Boolean
        Return value &amp;gt;= Me.MinValue AndAlso value &amp;lt;= Me.MaxValue
    End Function

End Class

&lt;/pre&gt;
&lt;p&gt;When you create the IntegerRangeWithGeneric class you get a helping hand from the IDE. When you press enter at the end of &amp;ldquo;Inherits NumberRange(Of Integer)&amp;rdquo; the IDE creates a stub of the IsValid method for you with the correct parameter type.&lt;/p&gt;
&lt;p&gt;In wrapping up just a few quick notes on creating generic classes.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Its only convention to name the generic type as T. Our class could have been Class NumberRange(Of WhatEver) &lt;/li&gt;
&lt;li&gt;You can have multiple generic types when declaring a class. eg NumberRange(Of TValue, TWhatEver).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Source Code with Unit Tests&lt;/p&gt;
&lt;p&gt;&lt;a href="/file.axd?file=2009%2f7%2fCreatingGenericClasses.zip"&gt;CreatingGenericClasses.zip (18.09 kb)&lt;/a&gt;&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:39 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Create-Generic-Classes</guid></item><item><title>Creating a MVC MapRoute for {year} as a root folder</title><link>http://www.26tp.com:80/blog/Creating-a-MVC-MapRoute-for-7byear7d-as-a-root-folder</link><description>&lt;p&gt;By default an ASP.NET MVC application has one URL routing rule: {controller}/{action}/{id}. With this routing rule in place MVC will interpret the URL /products/edit/2 as: using the ProductsController execute the Edit method with ID parameter of 2. The ProductsController.Edit method is responsible for retrieving product 2 from the database and passing it onto to /Views/Products/Edit.aspx. Edit.aspx is responsible for displaying the edit form.&lt;/p&gt; &lt;p&gt;Not surprisingly MVC gives us the power add additional routing rules. Routing rules (including the default) are defined by RegisterRoutes method in global.asax.vb.&lt;/p&gt; &lt;h2&gt;Creating a Route&lt;/h2&gt; &lt;p&gt;New routes are created via the RoutesCollection.MapRoute method. There are several MapRoute overload method but for our situation we need only use this overload: MapRoute(name, url, defaults, constraints).&lt;/p&gt; &lt;ul&gt; &lt;li&gt;name: Unique name for the route.  &lt;li&gt;url: URL we are routing with each part of the url enclosed in {}. eg {Controller}/{Action}/{Id}.  &lt;li&gt;defaults: Anonymous object to defining default values for the route.  &lt;li&gt;constraints: Anonymous object defining rules to define it the URL being tested can is valid for this map.&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;defaults&lt;/h3&gt; &lt;p&gt;The defaults parameter in MapRoute is an anonymous object to define default values for items that may be used by the constraints and/or the controller. A typical defaults parameter is:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;New With {.controller = &amp;lt;controller name&amp;gt;, .action = [Details|Edit|Create]}&lt;/pre&gt;
&lt;h2&gt;constraints&lt;/h2&gt;
&lt;p&gt;The constraints parameter can accept a regular expression or class that implements IRouteConstraint. IRouteConstraint has one method to implement: Match. Match accepts serveral parameters but must return True or False.&amp;nbsp; A typical contraints parameter is:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;New With {.result = New MyConstraint()}
&lt;/pre&gt;
&lt;h2&gt;Requirements &lt;/h2&gt;
&lt;p&gt;In this post I’m going to explain how to implement routing to satisfy the following requirements. The main table in the application is a list of competitions. Each competition has a start date. Therefore it seems appropriate that the basic folder structure of the site is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;/{year} - Lists all the competitions in starting in &amp;lt;year&amp;gt;. 
&lt;li&gt;/{year}/Create – Create a new competition. 
&lt;li&gt;/{year}/{slug} - Show the details of the competition in &amp;lt;year&amp;gt; with &amp;lt;slug&amp;gt; name. 
&lt;li&gt;/{year}/{slug}/Edit – Edit the selected competition. &lt;/li&gt;&lt;/ol&gt;
&lt;h2&gt;Handling the /{year} and /{year}/Create URL&lt;/h2&gt;&lt;pre class="brush: vb;"&gt;routes.MapRoute( _
   name:="year", _
   url:="{year}/{action}", _
   defaults:=New With {.controller = "Competitions", .action = "Index"}, _
   constraints:=New With {.year = New YearConstraint("Index", "Create")} _
)

&lt;/pre&gt;
&lt;p&gt;This routing rule will be used when a URL is /{year}, /{year}/Index or /{year}/Create. This is achieved by MVC testing the current URL against the url parameter for this routing rule and the YearConstraint.Match method returns True. If the routing rule passes these tests then the method defined by {action} will be executed against CompetitionsController.&lt;/p&gt;
&lt;h2&gt;Handling the /{year}/{slug} and /{year}/{slug}/Edit URL&lt;/h2&gt;&lt;pre class="brush: vb;"&gt;routes.MapRoute( _
   name:="year/slug", _
   url:="{year}/{slug}/{action}", _
   defaults:=New With {.controller = "Competitions", .action = "Details"}, _
   constraints:=New With {.year = New YearConstraint("Details", "Edit")} _
)

&lt;/pre&gt;
&lt;p&gt;When MVC processes the URL /2009/aus-open it will call CompetitionsController.Details(year:=2009, slug:”aus-open”). The Details method is called in this instance because it was defined as the default action and no action was defined in the URL.&lt;/p&gt;
&lt;p&gt;A URL of form /2009/aus-open/Edit will call CompetitionsController.Edit(year:=2009, slug:=”aus-open”).&lt;/p&gt;
&lt;h2&gt;YearConstraint&lt;/h2&gt;
&lt;p&gt;Our YearConstraint class implements the IRouteConstraint interface and has the following constructor.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Sub New(ByVal ParamArray allowableActions As String())

    ReDim mAllowableActions(allowableActions.Length - 1)

    For index = 0 To allowableActions.Length - 1
        mAllowableActions(index) = allowableActions(index).ToLower
    Next

End Sub&lt;/pre&gt;
&lt;p&gt;The constuctor accepts a variable number of acceptable actions (eg Details, Index, Edit). It then stores them in lower case in the private field.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Function Match(ByVal httpContext As System.Web.HttpContextBase, ByVal route As System.Web.Routing.Route, ByVal parameterName As String, ByVal values As System.Web.Routing.RouteValueDictionary, ByVal routeDirection As System.Web.Routing.RouteDirection) As Boolean Implements System.Web.Routing.IRouteConstraint.Match

    Dim year As String = CStr(values("year"))
    Dim action As String = CStr(values("action"))

    Return Me.IsValidYear(year) AndAlso mAllowableActions.Contains(action.ToLower)

End Function&lt;/pre&gt;
&lt;p&gt;The above Match method is called by MVC each time our route rule passes the URL test. In this case we only need use the values dictionary to get the year and action values from the URL to perform our final test.&lt;/p&gt;
&lt;p&gt;I hope this has helped you define your own routing rules.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:38 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Creating-a-MVC-MapRoute-for-7byear7d-as-a-root-folder</guid></item><item><title>Compressing CSS and JS files</title><link>http://www.26tp.com:80/blog/Compressing-CSS-and-JS-files</link><description>&lt;p&gt;There are 2 reasons why you want to compress your CSS and JS files before publishing your website:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reduces the size of files to be downloaded on client&amp;rsquo;s machine. In my experience 10 to 20k, not much but every bit helps. &lt;/li&gt;
&lt;li&gt;Reduces the number of files to download with help performance for the client as well.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;First step in compressing the files is to combine the same type of file into one file. Good old DOS COPY command will do the job for you.&lt;/p&gt;
&lt;pre class="brush: plain;"&gt;cmd /c copy /A file1.css+file2.css+file3.css temp.combined.css /B /Y
&lt;/pre&gt;
&lt;p&gt;Thanks to &lt;a href="http://stackoverflow.com/users/17495/eugensk00"&gt;eugensk00&lt;/a&gt; on &lt;a href="http://stackoverflow.com/"&gt;stackoverflow.com&lt;/a&gt; (&lt;a href="http://stackoverflow.com/questions/301442/how-do-i-concatenate-javascript-files-into-one-file"&gt;How do I concatenate JavaScript files into one file?&lt;/a&gt;) for that piece of info.&lt;/p&gt;
&lt;p&gt;Next step is to use &lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;YUI Compressor&lt;/a&gt; to strip out whitespace and the like.&lt;/p&gt;
&lt;pre class="brush: plain;"&gt;java.exe -jar yuicompressor-2.4.2.jar --type css --verbose temp.combined.css -o min.css
&lt;/pre&gt;
&lt;p&gt;Now just change your HTML to point to the compressed file and you&amp;rsquo;re set to go.&lt;/p&gt;
&lt;p&gt;To follow is a VBScript file to run the process for me.&lt;/p&gt;
&lt;pre class="brush: vb;"&gt;Option Explicit

Dim java, compressor, fso, shell, stylesFolder, scriptsFolder

java = "C:\Program Files\Java\jre6\bin\java.exe"
compressor = "C:\Program Files\YUI Compressor\2.4.2\build\yuicompressor-2.4.2.jar"
stylesFolder = "styles"
scriptsFolder = "scripts"

Set fso = CreateObject("Scripting.FileSystemObject")
Set shell = CreateObject("WScript.Shell")

CleanCssFolder
CombineCss "yui-reset-fonts-grids.css+yui-base-min.css+shCore.css+shThemeDefault.css"
CompressCss
CleanCssFolder

CleanJavaScriptFolder
CombineJavaScript "shCore.js+shBrushCSharp.js+shBrushCss.js+shBrushJScript.js" _
                            &amp;amp;"+shBrushSql.js+shBrushVb.js+shBrushXml.js+shLegacy.js"
CompressJavaScript
CleanJavaScriptFolder

' Delete the temp files from styles folder.
Sub CleanCssFolder

    CleanFolder stylesFolder
    
End Sub

' Delete the temp files from scripts folder.
Sub CleanJavaScriptFolder

    CleanFolder scriptsFolder
    
End Sub

' Delete all files in &amp;lt;subFolder&amp;gt; that starts with "compressed.".
Sub CleanFolder(subFolder)

    Dim folder, files, file
    
    Set folder = fso.GetFolder(subFolder)
    Set files = folder.Files
    
    For Each file in files
    
        If StartsWith(file.Name, "temp.") Then
            
            fso.DeleteFile file.Path
            
        End If
        
    Next
    
End Sub

' Combine the css files into temp.combined.css.
Sub CombineCss(fileNames)

    Combine fileNames, stylesFolder, "temp.combined.css"
    
End Sub

' Combine the js files into temp.combined.js.
Sub CombineJavaScript(fileNames)

    Combine fileNames, scriptsFolder, "temp.combined.js"
    
End Sub

' Combine &amp;lt;fileNames&amp;gt; in &amp;lt;subFolder&amp;gt; to &amp;lt;outputFileName&amp;gt;.
Sub Combine(fileNames, subFolder, outputFileName)

    Dim cmd
    
    cmd = "cmd /c copy /A {fileNames} {subFolder}\{outputFileName} /B /Y"

    ' Insert the sub folder into each of the file names.
    fileNames = subFolder &amp;amp; "\" &amp;amp; fileNames
    fileNames = Replace(fileNames, "+", "+{subFolder}\")
    
    cmd = Replace(cmd, "{fileNames}", fileNames)
    cmd = Replace(cmd, "{subFolder}", subFolder)
    cmd = Replace(cmd, "{outputFileName}", outputFileName)
  
    WScript.Echo "Combining files..."
    shell.Run cmd, 0, True

End Sub

' Compress the css files.
Sub CompressCss()

    Dim cmd
        
    cmd = CompressCommand("css", stylesFolder, "temp.combined.css", "min.css")
    WScript.Echo "Compressing temp.combined.css..."
    shell.Run cmd, 0, True

End Sub

' Compress the js files.
Sub CompressJavaScript()

    Dim cmd
        
    cmd = CompressCommand("js", scriptsFolder, "temp.combined.js", "min.js")
    
    ' todo: Temporary workaround. Compressor is breaking SyntaxHighlighter.
    ' cmd = "cmd /c copy {scriptsFolder}\temp.combined.js {scriptsFolder}\min.js"
    ' cmd = Replace(cmd, "{scriptsFolder}", scriptsFolder)
    
    WScript.Echo "Compressing temp.combined.js..."
    shell.Run cmd, 0, True

End Sub

' Returns the YUI compress command line.
Function CompressCommand(fileType, subFolder, inputFileName, outputFileName)

    CompressCommand = """{java}"" -jar ""{compressor}"" --type {fileType} --verbose ""{subFolder}\{inputFileName}"" -o ""{subFolder}\{outputFileName}"""
    CompressCommand = Replace(CompressCommand, "{java}", java)
    CompressCommand = Replace(CompressCommand, "{compressor}", compressor)
    CompressCommand = Replace(CompressCommand, "{fileType}", fileType)
    CompressCommand = Replace(CompressCommand, "{subFolder}", subFolder)
    CompressCommand = Replace(CompressCommand, "{inputFileName}", inputFileName)
    CompressCommand = Replace(CompressCommand, "{outputFileName}", outputFileName)
    
End Function

' Returns True if &amp;lt;text&amp;gt; starts with &amp;lt;startsWith&amp;gt;.
Function StartsWith(text, startsWithText)
    StartsWith = (Left(text, Len(startsWithText)) = startsWithText)
End Function    

&lt;/pre&gt;</description><pubDate>Sun, 08 May 2011 17:26:38 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Compressing-CSS-and-JS-files</guid></item><item><title>A LINQ to SQL Repository class for VB</title><link>http://www.26tp.com:80/blog/A-LINQ-to-SQL-Repository-class-for-VB</link><description>&lt;p&gt;There are blog posts to explain the Repository pattern better than I can. The following is an implementation of the Repository pattern tied to a LINQ to SQL DataContext.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;''' &amp;lt;summary&amp;gt;
''' Abstract Repository Class.
''' &amp;lt;/summary&amp;gt;
''' &amp;lt;typeparam name="TEntity"&amp;gt;The type of the entity/business object.&amp;lt;/typeparam&amp;gt;
''' &amp;lt;typeparam name="TKey"&amp;gt;The type of the unique key/id in entity.&amp;lt;/typeparam&amp;gt;
Public MustInherit Class Repository(Of TEntity As Class, TKey)

    Private mDataContext As DataContext

    ''' &amp;lt;summary&amp;gt;
    ''' Get the item from the database by its key field.
    ''' &amp;lt;/summary&amp;gt;
    ''' &amp;lt;param name="key"&amp;gt;Value to the unique key identifying the item to get.&amp;lt;/param&amp;gt;
    Public MustOverride Function [Get](ByVal key As TKey) As TEntity

    ''' &amp;lt;summary&amp;gt;
    ''' Initializes a new instance of the &amp;lt;see cref="Repository(Of TEntity, TKey)" /&amp;gt; class.
    ''' &amp;lt;/summary&amp;gt;
    ''' &amp;lt;param name="dataContext"&amp;gt;&amp;lt;see cref="System.Data.Linq.DataContext"/&amp;gt;&amp;lt;/param&amp;gt;
    Public Sub New(ByVal dataContext As DataContext)
        mDataContext = dataContext
    End Sub

    ''' &amp;lt;summary&amp;gt;
    ''' Get all the items from the database.
    ''' &amp;lt;/summary&amp;gt;
    Public Function Read() As IEnumerable(Of TEntity)
        Return Me.GetTable()
    End Function

    ''' &amp;lt;summary&amp;gt;
    ''' Add an item to the database on next call to save.
    ''' &amp;lt;/summary&amp;gt;
    Public Sub Add(ByVal item As TEntity)
        Me.GetTable().InsertOnSubmit(item)
    End Sub

    ''' &amp;lt;summary&amp;gt;
    ''' Delete the item from the databases on next call to save.
    ''' &amp;lt;/summary&amp;gt;
    ''' &amp;lt;param name="item"&amp;gt;The item.&amp;lt;/param&amp;gt;
    Public Sub Delete(ByVal item As TEntity)
        Me.GetTable().DeleteOnSubmit(item)
    End Sub

    ''' &amp;lt;summary&amp;gt;
    ''' Saves all pending changes to the database.
    ''' &amp;lt;/summary&amp;gt;
    Public Sub Save()
        mDataContext.SubmitChanges()
    End Sub

    ''' &amp;lt;summary&amp;gt;
    ''' Returns &amp;lt;see cref="System.Data.Linq.Table(Of TEntity)"/&amp;gt;.
    ''' &amp;lt;/summary&amp;gt;
    ''' &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    Private Function GetTable() As Table(Of TEntity)
        Return mDataContext.GetTable(Of TEntity)()
    End Function

End Class&lt;/pre&gt;
&lt;p&gt;The following is an implementation of the Repository class.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Class CompetitionsRepository
    Inherits Core.Repository(Of Competition, Integer)

    Public Sub New()
        MyBase.New(New CroquetScoresDataContext)
    End Sub

    Public Overrides Function [Get](ByVal key As Integer) As Competition
        Return (From comp In Me.Read Where comp.Key = key).SingleOrDefault
    End Function

End Class&lt;/pre&gt;
&lt;p&gt;And finally to use the class.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Sub UpdateCompetitionName()

    Dim repo As New CompetitionsRepository

    For Each competition In repo.Read

        competition.Name = competition.Name.ToUpper

    Next

    repo.Save()

End Sub
&lt;/pre&gt;</description><pubDate>Sun, 08 May 2011 17:26:37 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/A-LINQ-to-SQL-Repository-class-for-VB</guid></item><item><title>New Open Source Library</title><link>http://www.26tp.com:80/blog/New-Open-Source-Library</link><description>&lt;p&gt;Just started a new Open Source Library at &lt;a href="http://26tp.codeplex.com"&gt;http://26tp.codeplex.com&lt;/a&gt;. Over time I’ll be moving my library code into this library. I’ll blog about major updates, classes and extension methods as they are release.&lt;/p&gt; &lt;p&gt;I hope you find the library useful and at a very least a good learning tool.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:36 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/New-Open-Source-Library</guid></item><item><title>Unit testing, even the most trivial stuff, is important!</title><link>http://www.26tp.com:80/blog/Unit-testing-even-the-most-trivial-stuff-is-important!</link><description>&lt;p&gt;For the past 3 days I’ve started to learn and write PowerShell scripts. Its very different to programming in VB.NET or C# and its been hard work for what seem like simply tasks.&lt;/p&gt; &lt;p&gt;The mistake I make most is using commas to between parameters when calling a function. You don’t do that in PowerShell.&lt;/p&gt; &lt;p&gt;I’ve been writing Unit Tests well over a here now and have never doubted their benefit. And I’ve been trying to be more disciplined by using TDD but not always succeeding.&lt;/p&gt; &lt;p&gt;One of my doubts about TDD is some of the more trivial tests you are encouraged to write. For example you should test a method does throw an exception if the an argument value is unexpected. I’ve often thought what a waste of my time. Now that I’m writing in PowerShell can keep testing for argument values incorrectly I’ve truly found a benefit for all those tiny little tests.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:35 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Unit-testing-even-the-most-trivial-stuff-is-important!</guid></item><item><title>Arrange, Act, Assert comments help focus your Unit Test</title><link>http://www.26tp.com:80/blog/Arrange-Act-Assert-comments-help-focus-your-Unit-Test</link><description>&lt;p&gt;My first exposure to the &lt;strong&gt;A&lt;/strong&gt;rrange, &lt;strong&gt;A&lt;/strong&gt;ct &amp;amp; &lt;strong&gt;A&lt;/strong&gt;ssert (AAA) pattern for Unit Test was with MVC. Originally I thought what a waste of comments. I recently did so reading on the AAA and saw the light. Effectively my unit tests followed this pattern but not always clearly the case. Now the first thing I do when creating a unit test is to insert the AAA comments.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;&amp;lt;TestMethod()&amp;gt; Sub MethodName_ShouldReturnValue_WhenThisCase()

    ' Arrange

    ' Act

    ' Assert

End Sub
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It truly helps my focus and makes my unit test clean when I start this way.&lt;/p&gt;
&lt;p&gt;Do some &lt;a href="http://www.google.com.au/search?rlz=1C1CHMH_enAU318AU330&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=aaa+unit+test"&gt;Googlingly&lt;/a&gt; to find out more about AAA.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:34 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Arrange-Act-Assert-comments-help-focus-your-Unit-Test</guid></item><item><title>NSchema 0.2 - Introduction</title><link>http://www.26tp.com:80/blog/NSchema-20-Introduction</link><description>&lt;p&gt;Back in August 2009 I started creating NSchema. NSchema is yet another ORM so why did I write it? The main reason was performance. I felt that the top ORM open source solutions out there, namely NHibernate, were too slow. I wanted to develop an ORM that could run as near as quickly to has directly writing SQL code as possible. &lt;/p&gt; &lt;p&gt;NSchema 0.1 is up and working in production and overall I consider it a good framework. On the positive side:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;9.5 for performance.  &lt;li&gt;7 for usability.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;On the negative:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The code base is a hack feast.  &lt;li&gt;Not TDD and certainly not a unit test for every function.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The best way forward is to start with a clean code base and refer to NSchema 0.1 code base rather than try and clean it up. So its time to get on with it. Keep coming back to the &lt;a href="http://www.26tp.com/post/NSchema-20-Contents.aspx"&gt;NSchema 0.2 contents page&lt;/a&gt; to find out how things are progressing.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:33 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/NSchema-20-Introduction</guid></item><item><title>NSchema 0.2 - Contents</title><link>http://www.26tp.com:80/blog/NSchema-20-Contents</link><description>&lt;p&gt;This page will be constantly updated during the development on NSchema 0.2.&lt;/p&gt; &lt;table border="0" cellspacing="0" cellpadding="2" width="852"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;Day&lt;/td&gt; &lt;td valign="top" width="133"&gt;Time Spent&lt;/td&gt; &lt;td valign="top" width="584"&gt;Blog&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;0&lt;/td&gt; &lt;td valign="top" width="133"&gt;20 mins&lt;/td&gt; &lt;td valign="top" width="584"&gt;&lt;a href="http://www.26tp.com/post/NSchema-20-Introduction.aspx"&gt;Introduction to NSchema 0.2&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="584"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="584"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="584"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="584"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="584"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="584"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="584"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="133"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="584"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;</description><pubDate>Sun, 08 May 2011 17:26:32 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/NSchema-20-Contents</guid></item><item><title>Start Chrome with pages that were open when you last closed it</title><link>http://www.26tp.com:80/blog/Start-Chrome-with-pages-that-were-open-when-you-last-closed-it</link><description>&lt;pre class="brush: bat;"&gt;"%LocalAppData%\Google\Chrome\Application\chrome.exe" -restore-last-session
&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;&lt;font face="Segoe UI"&gt;&lt;/font&gt;&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:31 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Start-Chrome-with-pages-that-were-open-when-you-last-closed-it</guid></item><item><title>Restart PC and load applications</title><link>http://www.26tp.com:80/blog/Restart-PC-and-load-applications</link><description>&lt;p&gt;Even with Windows 7 (which I love by the way) it seems I still need to reboot my pc a handful times a day. Not pinned down way but its something to do with Visual Studio and unit tests; I think!&lt;/p&gt; &lt;p&gt;Big deal you say, just hit the reset button. Well my problem with that is I then have to load my applications up again. Of course I could just add links to the Startup folder but I don’t always want to load the applications. The solution is two batch installed on the desktop and a shortcut in the Startup folder.&lt;/p&gt; &lt;h2&gt;Restart.bat&lt;/h2&gt;&lt;pre class="brush: bat;"&gt;@echo off 

REM Create RunStartup.yes file so Startup.bat will know it should load the applications.
REM ------------------------------------------------------------------------------------
echo Start applications on reboot &amp;gt; RunStartup.yes

REM Restart the PC allowing the user to save documents etc.
REM -------------------------------------------------------
shutdown.exe /r /t 0
&lt;/pre&gt;
&lt;p&gt;Restart.bat creates the RunStartup.yes file and then restarts your PC.&lt;/p&gt;
&lt;h2&gt;Startup.bat&lt;/h2&gt;&lt;pre class="brush: bat;"&gt;@echo off
REM If no parameters passed to Startup.bat then run the applications.
REM -----------------------------------------------------------------
IF "%1"=="" GOTO RunStartup

REM Parameter was passed so goto requested label in batch file.
REM -----------------------------------------------------------
GOTO %1

:RunStartupIfFileExists

REM If RunStartup.yes file does not exist then nothing to do.
REM -----------------------------------------------------
IF NOT EXIST RunStartup.yes GOTO END

REM Delete the RunStartup file so Startup.bat does not automatically start&lt;br&gt;REM applications next time.
REM ----------------------------------------------------------------------
DEL RunStartup.yes

GOTO RunStartup

:RunStartup

start /d "C:\Program Files (x86)\TweetDeck" TweetDeck.exe
start /d "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\" devenv.exe
start /d "C:\Users\TimMurphy\AppData\Local\Google\Chrome\Application" chrome.exe -restore-last-session
start explorer "C:\Users\TimMurphy\Code" 

:End
&lt;/pre&gt;
&lt;p&gt;Startup.bat runs the applications I’m usually working on. If the batch file is run without an parameter then the applications are loaded. If RunStartupIfFilesExists is passed to Startup.bat then the applications are only loaded if RunStartup.yes file exists.&lt;/p&gt;
&lt;p&gt;The last file to this process it a shortcut in the Startup folder with the parameter RunStartupIfFileExists.&lt;/p&gt;
&lt;p&gt;So now when I want to restart the PC and load my usual programs I just double-click Restart.bat on my desktop.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:31 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Restart-PC-and-load-applications</guid></item><item><title>Code Snippet for Test Methods</title><link>http://www.26tp.com:80/blog/Code-Snippet-for-Test-Methods</link><description>&lt;p&gt;I previously blog that &lt;a href="http://www.26tp.com/post/Arrange-Act-Assert-comments-help-focus-your-Unit-Test.aspx"&gt;Arrange Act Assert Comments help focus your unit test&lt;/a&gt;. Now for a code snippet to help implement that idea. &lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"&amp;gt;
  &amp;lt;CodeSnippet Format="1.0.0"&amp;gt;
    &amp;lt;Header&amp;gt;
      &amp;lt;Title&amp;gt;Define a Test Method&amp;lt;/Title&amp;gt;
      &amp;lt;Author&amp;gt;Tim Murphy&amp;lt;/Author&amp;gt;
      &amp;lt;Description&amp;gt;Defines a Test Method with AAA comments.&amp;lt;/Description&amp;gt;
      &amp;lt;Shortcut&amp;gt;TM&amp;lt;/Shortcut&amp;gt;
    &amp;lt;/Header&amp;gt;
    &amp;lt;Snippet&amp;gt;
      &amp;lt;Declarations&amp;gt;
        &amp;lt;Literal&amp;gt;
          &amp;lt;ID&amp;gt;Method&amp;lt;/ID&amp;gt;
          &amp;lt;Type&amp;gt;String&amp;lt;/Type&amp;gt;
          &amp;lt;ToolTip&amp;gt;Replace this with method to be tested.&amp;lt;/ToolTip&amp;gt;
          &amp;lt;Default&amp;gt;Method&amp;lt;/Default&amp;gt;
        &amp;lt;/Literal&amp;gt;
        &amp;lt;Literal&amp;gt;
          &amp;lt;ID&amp;gt;Expects&amp;lt;/ID&amp;gt;
          &amp;lt;Type&amp;gt;String&amp;lt;/Type&amp;gt;
          &amp;lt;ToolTip&amp;gt;Replace this with what the method is expected to do.&amp;lt;/ToolTip&amp;gt;
          &amp;lt;Default&amp;gt;Expects&amp;lt;/Default&amp;gt;
        &amp;lt;/Literal&amp;gt;
        &amp;lt;Object&amp;gt;
          &amp;lt;ID&amp;gt;When&amp;lt;/ID&amp;gt;
          &amp;lt;Type&amp;gt;String&amp;lt;/Type&amp;gt;
          &amp;lt;ToolTip&amp;gt;Replace this with the condition the method is testing.&amp;lt;/ToolTip&amp;gt;
          &amp;lt;Default&amp;gt;When&amp;lt;/Default&amp;gt;
        &amp;lt;/Object&amp;gt;
      &amp;lt;/Declarations&amp;gt;
      &amp;lt;Code Language="VB" Kind="method decl"&amp;gt;
          &amp;lt;![CDATA[&amp;lt;TestMethod()&amp;gt; Public Sub $Method$_$Expects$_$When$()

        ' Arrange
        ' ---------------------------------------------------------------------

        ' Act
        ' ---------------------------------------------------------------------

        ' Assert
        ' ---------------------------------------------------------------------

    End Sub]]&amp;gt;&amp;lt;/Code&amp;gt;
    &amp;lt;/Snippet&amp;gt;
  &amp;lt;/CodeSnippet&amp;gt;
&amp;lt;/CodeSnippets&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After installing the snippet just type &lt;strong&gt;tm&lt;/strong&gt; then tab and you get:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;&amp;lt;TestMethod()&amp;gt; Public Sub Method_Expects_When()

    ' Arrange
    ' ---------------------------------------------------------------------

    ' Act
    ' ---------------------------------------------------------------------

    ' Assert
    ' ---------------------------------------------------------------------

End Sub

&lt;/pre&gt;</description><pubDate>Sun, 08 May 2011 17:26:30 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Code-Snippet-for-Test-Methods</guid></item><item><title>Example: DataGridView</title><link>http://www.26tp.com:80/blog/Example-DataGridView</link><description>&lt;p&gt;This is the first in a series of &lt;a href="http://www.26tp.com/?tag=/examples"&gt;examples&lt;/a&gt; on databinding, MVC and related matters using .NET Framework, Visual Studio 2008 &amp;amp; VB.NET.&lt;/p&gt; &lt;p&gt;The purpose of this example is to show how to quickly and easily develop a form with a DataGridView, Navigation and the ability to load data. It is purposely simplistic in nature and future examples will provide best practice and real world examples.&lt;/p&gt; &lt;p&gt;Source code for all examples can be found at &lt;a href="http://26tp.codeplex.com"&gt;http://26tp.codeplex.com&lt;/a&gt;. 26tp.Examples.DataGridView is the project for this blog.&lt;/p&gt; &lt;h2&gt;Models.Contact&lt;/h2&gt; &lt;p&gt;Models.Contact is a very simple class with the following properties:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;FirstName  &lt;li&gt;LastName  &lt;li&gt;Birthday  &lt;li&gt;Cars  &lt;li&gt;Age: Read only, calculated from their birthday to today.  &lt;li&gt;FullName: Read only, FirstName + “ “ + LastName.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Excerpt of class.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Namespace Models

    Public Class Contact

        Private mFirstName As String
        Public Property FirstName() As String
            Get
                Return mFirstName
            End Get
            Set(ByVal value As String)
                mFirstName = value
            End Set
        End Property

        ...

        Public ReadOnly Property Age() As Long?
            Get

                If Not mBirthday.HasValue Then
                    Return Nothing
                End If

                Dim years = Now.Year - mBirthday.Value.Year

                If New Date(mBirthday.Value.Year, Now.Month, Now.Day) &amp;lt; mBirthday.Value Then
                    years -= 1
                End If

                Return years

            End Get
        End Property

        Public ReadOnly Property FullName() As String
            Get
                Return CStr(mFirstName + " " + mLastName).Trim
            End Get
        End Property

    End Class

End Namespace
&lt;/pre&gt;
&lt;h2&gt;Creating the DataGridView&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create a blank form. 
&lt;li&gt;Add a StatusStrip. 
&lt;li&gt;Add a Panel docked to the right. This will be used to host buttons and labels that will be created later. 
&lt;li&gt;Add Models.Contact to Data Sources via the Data –&amp;gt; Add New Data Source menu option. 
&lt;li&gt;Finally drag the Models.Contact Data Source onto the window and dock it into the Parent Container.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Hit F5 and you have a working DataGridView. FullName changes when you enter FirstName and/or LastName. Age changes when you enter a Birthday.&lt;/p&gt;
&lt;h2&gt;Load Existing Data&lt;/h2&gt;
&lt;p&gt;To load existing data the ContactBindingSource.DataSource needs to be updated.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Class Contacts

    Private mContacts As New BindingList(Of Models.Contact)

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)

        Me.ContactBindingSource.DataSource = mContacts

    End Sub

    Private Sub LoadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LoadButton.Click

        mContacts = New BindingList(Of Models.Contact)((New Models.ContactRepository).FindAll)
        Me.ContactBindingSource.DataSource = mContacts

    End Sub

End Class
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the above code the mContacts was introduced as the container for our fake contacts. A BindingList is used so any changes we make to mContacts will be recognised by ContactBindingSource and shown in the data grid.&lt;/p&gt;
&lt;p&gt;The ContactRepository.FindAll method simply returns a list of fake contacts.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Namespace Models

    Public Class ContactRepository

        Public Function FindAll() As List(Of Contact)

            Dim list = New List(Of Contact)

            list.Add(New Contact With {.FirstName = "Edna", .LastName = "Kimble", .Birthday = New Date(1957, 12, 24)})
            list.Add(New Contact With {.FirstName = "Maria", .LastName = "Fenimore", .Birthday = New Date(1946, 7, 7)})
            list.Add(New Contact With {.FirstName = "John", .LastName = "Bateman", .Birthday = New Date(1970, 2, 8)})
            list.Add(New Contact With {.FirstName = "James", .LastName = "Ferguson", .Birthday = New Date(1967, 7, 8)})
            list.Add(New Contact With {.FirstName = "Debra", .LastName = "Lyons", .Birthday = New Date(2010, 1, 1)})

            Return list

        End Function

    End Class

End Namespace

&lt;/pre&gt;
&lt;p&gt;The next blog in the &lt;a href="http://www.26tp.com/?tag=/examples"&gt;Examples&lt;/a&gt; series will look at implementing INotifyPropertyChanged.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:29 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Example-DataGridView</guid></item><item><title>Example: Implementing INotifyPropertyChanged</title><link>http://www.26tp.com:80/blog/Example-Implementing-INotifyPropertyChanged</link><description>&lt;p&gt;In the previous example &lt;a href="http://www.26tp.com/post/Example-DataGridView.aspx"&gt;DataGridView&lt;/a&gt; we had a very simple Models.Contact class being displayed in a DataGridView. In this post we will look at how and why to implement INotifyPropertyChanged interface on the Models.Contact.&lt;/p&gt; &lt;h2&gt;Why&lt;/h2&gt; &lt;p&gt;It is time to be generous and give away some cars :-)&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Private Sub GiveCarButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GiveCarButton.Click

    Dim contact As Models.Contact = Me.ContactBindingSource.Current

    If contact Is Nothing Then

        MessageBox.Show("Must be on a current record to give away a car.", "Car Give Away", MessageBoxButtons.OK, MessageBoxIcon.Information)

    End If

    If MessageBox.Show(String.Format("Give a car away to '{0}'?", contact.FullName), "Car Give Away", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then

        contact.Cars += 1

    End If

End Sub

&lt;/pre&gt;
&lt;p&gt;Pretty simple but the grid/edit window that raises this event will not display the new number cars. Updating Models.Contacts to implement the INotifyPropertyChanged interface will fix this problem.&lt;/p&gt;
&lt;h2&gt;How&lt;/h2&gt;&lt;pre class="brush: vb;"&gt;Imports System.ComponentModel

Namespace Models

    Public Class Contact
        Implements INotifyPropertyChanged

        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

        ...

        Private mCars As Integer
        Public Property Cars() As Integer
            Get
                Return mCars
            End Get
            Set(ByVal value As Integer)
                If mCars &amp;lt;&amp;gt; value Then
                    mCars = value
                    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Cars"))
                End If
            End Set
        End Property

        ...

    End Class

End Namespace
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;With the above change to our property any control that is bound to Models.Contact will be aware of any changes made to the underlying data. We need to update every property and in the codes current form that would be time consuming and error prone. A future post will look at refactoring Models.Contact.&lt;/p&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;p&gt;The example can be downloaded from &lt;a href="http://26tp.codeplex.com"&gt;http://26tp.codeplex.com&lt;/a&gt;, project 26tp.Examples.ImplementINotifyPropertyChanged.&lt;/p&gt;
&lt;p&gt;This example has two forms, Grid &amp;amp; Edit. Each form has a &lt;strong&gt;Notify Property Changes&lt;/strong&gt; checkbox. Try giving a car away with the checkbox ticked and unticked to see the effect of raise the PropertyChanged event.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:28 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Example-Implementing-INotifyPropertyChanged</guid></item><item><title>Building a MVP Framework: Table of Contents</title><link>http://www.26tp.com:80/blog/Building-a-MVP-framework-Table-of-Contents</link><description>&lt;p&gt;Lately I’ve spent a reasonable amount of time with ASP.NET MVC and grown to love the pattern.&amp;nbsp; My current project is a Windows Form application and in need of help from a similar. Having spent the last two days researching the topic I’ve not been able to find a framework that I’m satisfied. Largely they are under documented or overly complex. I’m trying to make development easier that harder!&lt;/p&gt; &lt;p&gt;To quote a &lt;a href="http://www.hanselman.com/"&gt;Scott Hansleman&lt;/a&gt; blog &lt;a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx"&gt;post&lt;/a&gt; I read recently “If you don't like something, fix it.”. I have a very pressing need and short deadline for the current project. In other words to begin with it’s going to be a hack fest. The main concern will be to get the job done, worry about the pretty stuff later on.&lt;/p&gt; &lt;p&gt;Wish me luck.&lt;/p&gt; &lt;h2&gt;Table of Contents&lt;/h2&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx"&gt;The Goals&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-2-The-Application-Window.aspx"&gt;The Application Window&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-3-The-About-Dialog.aspx"&gt;The About Dialog&lt;/a&gt; &lt;li&gt;…&lt;/li&gt;&lt;/ol&gt;</description><pubDate>Sun, 08 May 2011 17:26:27 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Building-a-MVP-framework-Table-of-Contents</guid></item><item><title>Building a MVP Framework: Part 1: The Goals</title><link>http://www.26tp.com:80/blog/Building-a-MVP-Framework-Part-1-The-Goals</link><description>&lt;p&gt;In Part 1 of the &lt;a href="http://www.26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx"&gt;Building a MVP Framework&lt;/a&gt; series I’m going to define the goals of the sample application and the framework itself.&lt;/p&gt; &lt;h2&gt;Framework Goals&lt;/h2&gt; &lt;p&gt;The goals of any Framework are (or at least should be) determined by the requirements of the applications that will use the Framework. The MVP Framework must address the following needs.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Separation of UI and Business Logic code.  &lt;li&gt;Thin UI.  &lt;li&gt;Easy to implement.  &lt;li&gt;Easy to Unit Test a very high percentage of the application.&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;Sample Application Goals&lt;/h2&gt; &lt;p&gt;In this series I’ll be using the &lt;a href="http://chinookdatabase.codeplex.com/"&gt;Chinook Database&lt;/a&gt; imported into a SQLite database. Initially the application will have &lt;strike&gt;five&lt;/strike&gt; six forms.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Application Window.  &lt;li&gt;Welcome Dialog.  &lt;li&gt;Create SQLite database from SQL file.  &lt;li&gt;Edit Artists. Very simple form allowing scrolling throw the list of Artists and editing.  &lt;li&gt;Grid of Artists. Very simple form display a grid of Artists with editing.  &lt;li&gt;Artists Explorer. The explorer will have three panels: Tree, Grid &amp;amp; Edit. The explorer will use and display data from the Artist, Album, Track, PlaylistTrack &amp;amp; Playlist tables of the Chinook Database.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In Part 2, &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-2-The-Application-Window.aspx"&gt;The Application Window&lt;/a&gt;, I’ll look at the first implementation of MVP.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:26 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Building-a-MVP-Framework-Part-1-The-Goals</guid></item><item><title>Building a MVP Framework: Part 2: The Application Window</title><link>http://www.26tp.com:80/blog/Building-a-MVP-Framework-Part-2-The-Application-Window</link><description>&lt;p&gt;In &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx"&gt;Part 1&lt;/a&gt; of &lt;a href="http://www.26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx"&gt;series&lt;/a&gt; I said there would be five forms; in fact there are six. I forgot about the application window. The application window needs a title and link in the status bar to this series’ table of contents.&lt;/p&gt; &lt;p&gt;In Part 2 of the&amp;nbsp; series I’m going to design and implement a simple Welcome Dialog. Personally I hate Welcome Dialogs but its nice and simple to get the ball rolling.&lt;/p&gt; &lt;p&gt;The dialog will display:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Application Name  &lt;li&gt;Version  &lt;li&gt;Web Link  &lt;li&gt;OK button&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;Application Startup&lt;/h2&gt; &lt;p&gt;Later in this post I’ll describe the Presenter class but for now suffice to say it is god in an MVP application. That being the case we need to change the default startup routine of the WinForm project. Create a module with a public sub main:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Module Main

    Public Sub Main()

        Dim appWindowPresenter = New AppWindowPresenter

        Application.Run(appWindowPresenter.StartupForm)

    End Sub

End Module
&lt;/pre&gt;
&lt;p&gt;The name of the module is not important but the procedure must be named Main.&lt;/p&gt;
&lt;p&gt;Next go into the project properties and untick the &lt;strong&gt;Enable application framework&lt;/strong&gt; option and select Sub Main as the &lt;strong&gt;Startup object&lt;/strong&gt; (must be done in that order.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.26tp.com/image.axd?picture=ApplicationStartup.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ApplicationStartup" border="0" alt="ApplicationStartup" src="http://www.26tp.com/image.axd?picture=ApplicationStartup_thumb.png" width="664" height="331"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;The Presenter&lt;/h2&gt;
&lt;p&gt;As previously mentioned the Presenter is god. It is responsible for constructing the form, serving data to the form and responding to UI events.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Class AppWindowPresenter

    Private mStartupForm As AppWindow

    Public Sub New()
        mStartupForm = New AppWindow(me)
    End Sub

    Public ReadOnly Property StartupForm() As AppWindow
        Get
            Return mStartupForm
        End Get
    End Property

End Class
&lt;/pre&gt;
&lt;p&gt;As you can see in the above code the AppWindowPresenter has a reference to the AppWindow form is constructs and AppWindow has a reference to AppWindowPresenter. This is required so when form receives a UI event it can talk to the presenter and the presenter can talk back to the window.&lt;/p&gt;
&lt;h2&gt;The Model&lt;/h2&gt;
&lt;p&gt;The AppWindow needs to set the text for it’s title and status bars; it does this via a Model. A Model is simple a data object, entity call it what you like. In this series of example class names ending with Model refer to object holding raw data from the database. Classes ending with ViewModel are objects tailor made for a View.&lt;/p&gt;
&lt;p&gt;The AppWindowViewModel has just three readonly properties Name, BlogTitle and BlogURL.&lt;/p&gt;
&lt;h2&gt;Binding The Data&lt;/h2&gt;
&lt;p&gt;Now we have the model and the application window being displayed we need the application window to update itself with the values in the model. A quick change the presenter constructor:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Sub New()
    mModel = New AppWindowViewModel
    mStartupForm = New AppWindow(Me)
    mStartupForm.BindData()
End Sub
&lt;/pre&gt;
&lt;p&gt;Followed by adding AppWindow.BindData() method:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Sub BindData()
    Me.Text = mPresenter.Model.Name
    Me.BlogToolStripStatusLabel.Text = mPresenter.Model.BlogTitle
End Sub&lt;/pre&gt;
&lt;p&gt;Now when the application starts the application title bar and status bar are updated with the required buttons.&lt;/p&gt;
&lt;h2&gt;The Unit Tests&lt;/h2&gt;
&lt;p&gt;So far I’ve not mention unit tests. Well of course I’ve been writing this as we go. As you can imagine the unit tests for the AppWindowPresenter and AppWindowViewModel class are very quick and easy to implement. The AppWindow tests are equally easy.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;&amp;lt;TestClass()&amp;gt; Public Class AppWindow_Tests

    &amp;lt;TestMethod()&amp;gt; Public Sub CanConstruct()

        ' Arrange

        ' Act
        Dim value = New AppWindow(New AppWindowPresenter)

        ' Assert
        value.ShouldNotBeNull()

    End Sub

    &amp;lt;TestMethod()&amp;gt; Public Sub AppWindow_BindsData()

        ' Arrange
        Dim presenter = New AppWindowPresenter

        ' Act
        Dim frm = presenter.StartupForm()

        ' Assert
        frm.Text.ShouldEqual(presenter.Model.Name)
        frm.BlogToolStripStatusLabel.Text.ShouldEqual(presenter.Model.BlogTitle)

    End Sub

End Class
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you can see the we have been able to test every method in the AppWindow with very little pain or fanfare.&lt;/p&gt;
&lt;h2&gt;Source Code&lt;/h2&gt;
&lt;p&gt;Source code is available for this post via SVN:&lt;/p&gt;&lt;pre class="brush: bat;"&gt;svn export "https://26tp.svn.codeplex.com/svn/tags/Building a MVP Framework - Part 2"
&lt;/pre&gt;
&lt;p&gt;Or to get the latest copy of the complete series code:&lt;/p&gt;&lt;pre class="brush: bat;"&gt;svn export https://26tp.svn.codeplex.com/svn/trunk/
&lt;/pre&gt;
&lt;p&gt;View the 26tp.Examples.MVP project via the 26tp.Examples.sln solution.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this post we can created our first Presenter, Model &amp;amp; Form classes along with accompanying unit tests. So far the framework has meet all the goals set out in &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx"&gt;Part 1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Has it been worth it. It would have been quicker and easy just to design the AppWindow in Visual Studio, use the properties window to set the required values and we could write unit tests for this. But one positive side effect is we can easily read the code to see exactly have properties have been set. Using the MVP pattern we are able to create the AppWindow with the designer and the only properties we change in the designer is the name of the controls.&lt;/p&gt;
&lt;p&gt;In the next post, &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-3-The-About-Dialog.aspx"&gt;The About Dialog&lt;/a&gt;, we will look at using a BindingSource to bind the model to the form.&lt;/p&gt;</description><pubDate>Sun, 08 May 2011 17:26:25 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/Building-a-MVP-Framework-Part-2-The-Application-Window</guid></item><item><title>How to install Python and CGI scripts on Windows Server 2003</title><link>http://www.26tp.com:80/blog/How-to-install-Python-and-CGI-scripts-on-Windows-Server-2003</link><description>&lt;ol&gt; &lt;li&gt;Download and install required version of &lt;a href="http://www.python.org/download/"&gt;Python&lt;/a&gt;.  &lt;li&gt;Open &lt;strong&gt;Internet Information Services&lt;/strong&gt;.  &lt;li&gt;Open the &lt;strong&gt;Properties&lt;/strong&gt; dialog for web site that required Python CGI scripts.  &lt;li&gt;Go to the &lt;strong&gt;Home Directory&lt;/strong&gt; tab.  &lt;li&gt;Ensure &lt;strong&gt;Execute permissions&lt;/strong&gt; is set to &lt;strong&gt;Scripts Only&lt;/strong&gt;.  &lt;li&gt;Click the &lt;strong&gt;Configuration&lt;/strong&gt; button and select the &lt;strong&gt;Mappings&lt;/strong&gt; tab.  &lt;li&gt;Click &lt;strong&gt;Add…&lt;/strong&gt; button.  &lt;li&gt;Set the &lt;strong&gt;Executable&lt;/strong&gt; value to &lt;strong&gt;C:\Python26\python.exe -u "%s %s" &lt;/strong&gt;&lt;em&gt;(Change path appropriately)&lt;/em&gt;  &lt;li&gt;Set the &lt;strong&gt;Extension value&lt;/strong&gt; to &lt;strong&gt;.cgi&lt;/strong&gt;.  &lt;li&gt;Set &lt;strong&gt;Verbs&lt;/strong&gt; to &lt;strong&gt;All Verbs&lt;/strong&gt;.  &lt;li&gt;Tick &lt;strong&gt;Script engine&lt;/strong&gt; on.  &lt;li&gt;Tick &lt;strong&gt;Verify that file exists&lt;/strong&gt; on.  &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to return to the &lt;strong&gt;Application Configuration&lt;/strong&gt; dialog.  &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to return to the web site &lt;strong&gt;Properties&lt;/strong&gt; dialog.  &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to return to &lt;strong&gt;Internet Information Services&lt;/strong&gt; manager.  &lt;li&gt;Install a simple CGI script to test the installation.&lt;br&gt;&lt;pre class="brush: py;"&gt;print 'Status: 200 OK'
print 'Content-type: text/html'
print
 
print '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;'
print ''
print '&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;'
print ''
print ''
&lt;/pre&gt;
&lt;li&gt;Point your browser to the test script and hey presto it should be working.&lt;/li&gt;&lt;/ol&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://vampirebasic.blogspot.com/2009/06/running-mercurial-on-windows.html"&gt;&lt;font color="#0066cc"&gt;http://vampirebasic.blogspot.com/2009/06/running-mercurial-on-windows.html&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jeremyskinner.co.uk/mercurial-on-iis7/"&gt;&lt;font color="#0066cc"&gt;http://www.jeremyskinner.co.uk/mercurial-on-iis7/&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description><pubDate>Sun, 08 May 2011 17:26:24 GMT</pubDate><guid isPermaLink="true">http://www.26tp.com:80/blog/How-to-install-Python-and-CGI-scripts-on-Windows-Server-2003</guid></item></channel></rss>
