Monday, May 21, 2007

I think it is fair to say CruiseControl.NET has become synonymous with Continuous Integration in the .NET space.  In the recent DNR on CI* with Eric Sink and Martin Woodward it was the defacto choice for the discussion and with good reason.  CCNet is a great tool.

I just wanted to give a quick shout-out to Draco.NET which is also a CI server for .NET and while not having the broad featureset of CCNet I recommend it for smaller shops getting their first Continuous/Automated build together.  My two reasons are:

  • Supports Visual Source Safe, which like it or not is the Gateway Drug for source code control.  (To hear what I think of that go grab DNR #221 about 5min16sec in ;)  It also supports PVCS, Subversion and Vault.
  • It is so much easier to configure.  You have no options for reporting or postbuild steps, or overriding the build ID or RSS add-ons for.  CCNetConfig is essential for configuring CruiseControl.NET.  Draco.NET offers a pit of success for the folks new to CI.

The most compelling reason for CCNet over Draco.NET is Everyone else is using CCNet :-)

On the topic of DNR show #238 - Eric talks about Vault, but doesn't mention that you don't need to purchase a license when used for a single developer.  It is licensed by named accounts, so go get it and give it a go all you VSS folks!

*the best bit of the show is 11min45sec in... ;-)

Listening To: Ani Difranco - Revelling and Reckoning

Monday, May 21, 2007 8:06:12 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [2]  | 
 Tuesday, May 08, 2007

I was looking today at options for finishing a build with something other than an MSI or folder full of files:  An ISO file.

I am a fan of DaemonTools and associated add-ons.  Even if you're not planning to burn to disc, an ISO file can be a useful way of getting a bunch of files around the place.

First step was to grab a Windows binary of mkisofs from one of the various sources of cdrtools on the webNB:  It comes linked with Cygwin binaries.

This is a util that has its roots in the Linux/Unix world, so be prepared to scratch your head a bit if you are not familiar with the world of Linux/Unix command line tools.  Also if you are, don't be fooled by mkisofs following the naming convention of the other mk*fs tools.  It is really quite different.

In the *nix world, the online help is by the man ("manual") page system.  Basically, at your prompt you type man mkisofs for help with mkisofs.   This works in Google too!  The man page will be a useful reference, as will the less informative usage info you can get from mkisofs.exe -help

Having said all that, the following options are a really good place to start: 

Option Note
-J Enable Joilet (you want this)
-R Enable Rock Ridge (you want this)
-V diskname Set a volume label
-o filename.iso Set the output ISO file name
-graft-points allows "=" syntax in pathspec.  More on this below...
-m "*.tmp" Exclude files from the image by pattern

mkisofs takes paths to add to the ISO file as parameters, and by default all these are stacked under the root of the disk image.  If this is not what you want then you should enable graft points.  This option will allow you to make folders in your ISO image for each of the folders you are adding to the disk.

For example, the following pathspec will create two folders on the CD, one called Windows for the contents of the bin folder, and one called Documentation for the contents of the doco folder:

Windows=D:\build\windows\bin\ Documentation=D:\build\doco\

So the complete command line for mkisofs will be something like:

"C:\Program Files\cdrtools-latest\mkisofs.exe" -J -R -graft-points -quiet -o f:\backup.iso -V backup -m "*.tmp" Windows=D:\build\windows\bin\ Documentation=D:\build\doco\

For extra points, you can automatically burn the ISO to a disk using the cdburn / dvdburn tool that ships with the Windows Server 2003 Resource Kit Tools.

A couple of reasons I'll suggest using this over using cdrecord.exe that comes with the cdrtools package:

  • The cygwin-based tools don't work as well with later Win32 like Windows Server 2003, they seem to not deal with the tighter security well.
  • The syntax of cdburn/dvdburn is much much easier!

An example of the syntax to burn f:\backup.iso to the blank disc in the burner g:\ is:

C:\Program Files\Windows Resource Kits\Tools>cdburn.exe g: f:\backup.iso -speed max

Also note that the cdburn will eject the disk once it has been burnt!  Keep that in mind if your CD drive is normally behind a door or cage or something!

UPDATE:  This technique is also has some utility for backup-to-disk scenarios.  For example a backup batch file that made an ISO then burnt it to disk.

Listening to: Bend to Squares by Death Cab for Cutie

Tuesday, May 08, 2007 2:53:13 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [2]  | 
 Friday, April 20, 2007

Every so often I check that web service, just to see what it comes back with.... nothing yet ;-)

Nice to see it is still in Vista, my little magic 8-ball dialogue! 

I just wish I could control the default.

Friday, April 20, 2007 5:04:46 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, April 16, 2007

One of those things that makes sense, but you may have assumed otherwise if not had cause to ponder it.  I'm talking about literary translation, and the liberties that the translator and their editor have to take while translating books from foreign languages to English and vice versa.

In Other Words, is a three part series from Canada's CBC, available on their podcast where by some highly regarded literary translators discuss their trade.  They all take the topic of these liberties very seriously, and feel that at times being faithful to the original means straying from it.

In the second episode, one of the guest translators recounts a cartoon to illustrate the point, in which the translator asks the author of the original work: Do you not be happy with me as the translator of the books of you? 

The series examines the question that you may assume we are reading a fidelity reproduction of Don Quixote or Dostoyevsky, until you read a second translation and examine the differences.  How is the difference explained if both are correct?

The third and final part of the series is due to appear on the podcast feed tonight, and makes for very interesting listening.

Monday, April 16, 2007 1:59:50 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, April 12, 2007

This script came out of a discussion here at the office around a product that isn't flexible or location aware in how it writes datetime values into the database.

This is also not paying attention to storing the date data in UTC or localtime or any of those concerns, just the semantics of storing whatever the date value happens to be.

What are your experiences with this?  Comments as always most welcome :-)

Example script follows:


/*
    You can use the following proc at the start of your app to see
    what the current date format SQL Server is expecting from you
    based on the default language selection set on your login.

    Look at the dateformat field in the resultset of this proc.

    Use this if you want to honour the regional selection that has
    been setup on a per-user basis on the SQL Server
    (login properties of each user)
*/

exec sp_helplanguage @@language

/*
    Otherwise, you may also override the language settings if your
    application code can only format dates one way.

    This will avoid message 241 at runtime:    
        "The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value."

    The 15th of Feb is a good example because there is no 15th month:
*/


SET LANGUAGE us_english
go -- dateformat is now = mdy

select cast('2/15/2003' as datetime) as US_1
go
select cast('15/2/2003' as datetime) as US_2 --Expect Msg 242
go


SET LANGUAGE british
go -- dateformat is now = dmy

select cast('2/15/2003' as datetime) as British_1 --Expect Msg 242
go
select cast('15/2/2003' as datetime) as British_2
go

You can grab the script here: 20070412.deepdark.net_dmy_mdy.sql (1.14 KB)

Thursday, April 12, 2007 10:52:12 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, April 04, 2007

An MVP they call Brian referred me to a new Blog/RSS Feed client called FeedGhost.

It scratches my itch for a feed reader that can sync between multiple PCs through a subscription service, but the most impressive feature I have found so far is the UI.  It has set a new high water mark for me in the smartclient space. 

Check out the screen shots - but once installed you realize the screenshots don't do it justice. 

The timing of this news couldn't be better for me because I was reading my feeds on my "Beta Bliss" laptop - Vista RC1 & Office 2007 Beta 2 TR, and office expired 1st of April so I was in the market for a new feed reader.  I love it when things just come together :-)

Wednesday, April 04, 2007 11:06:11 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, March 26, 2007

So I feel that my last post on pretty gray info bars in Photoshop could do with a second chapter :)

This is a pretty long series so I'll be breif - what follows is the rough outline of how to achieve the same result as a User Control in your Visual Studio project.  The advantage of this aproach would be to allow you to dymanically add text or other sparkle of your own creation :-)

Here's a sample:

Code follows :-)

namespace GrayBar
{
   public partial class GrayBar : UserControl
   {
      public enum GrayBarModes
      {
         GreenTick = 0,
         YellowBang = 1,
         RedX = 2
      }

      public GrayBar()
      {
         InitializeComponent();
      }

      protected override void OnPaint(PaintEventArgs e)
      {
         Graphics g = this.CreateGraphics();
         g.SmoothingMode = SmoothingMode.HighQuality;

         // Fill the whole canvas
         Rectangle wholeControlSpace = new Rectangle(0, 0, this.Width, this.Height);
         Brush controlFiller = new LinearGradientBrush(wholeControlSpace, Color.DarkGray, Color.LightGray, LinearGradientMode.Vertical);
         g.FillRectangle(controlFiller, wholeControlSpace);

         // Make icon in corner
         Rectangle iconSpace = new Rectangle(1, 1, this.Height - 2, this.Height - 2);
         Brush iconFiller = new LinearGradientBrush(iconSpace, Color.Gray, Color.DarkGray, LinearGradientMode.Vertical);
         g.FillEllipse(iconFiller, iconSpace);
         base.OnPaint(e);

         Font iconFont = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular);
         string iconText = "";
         Brush iconTextBrush = new SolidBrush(Color.NavajoWhite);

         float fontHight = this.Height; 

         // The Font, Text and Colour depends on the setting on our GrayBarMode property
         switch (GrayBarMode)
         {
            case GrayBarModes.GreenTick:
               iconFont = new Font("Wingdings 2", fontHight, GraphicsUnit.Pixel);
               iconText = "P"; // P == "tick" in "Wingdings 2"
               iconTextBrush = new LinearGradientBrush(iconSpace, Color.DarkGreen, Color.LightGreen, LinearGradientMode.Vertical);
               break;
            case GrayBarModes.YellowBang:
               iconFont = new Font("Arial", fontHight, FontStyle.Bold, GraphicsUnit.Pixel);
               iconText = "!"
               iconTextBrush = new LinearGradientBrush(iconSpace, Color.Orange, Color.Yellow, LinearGradientMode.Vertical);
               break;
            case GrayBarModes.RedX:
               iconFont = new Font("Arial", fontHight, FontStyle.Bold, GraphicsUnit.Pixel);
               iconText = "X"
               iconTextBrush = new LinearGradientBrush(iconSpace, Color.Maroon, Color.Red, LinearGradientMode.Vertical);
               break;
            default:
               throw new ApplicationException("Unknow Mode");
         }

         float iconTextXPos = (iconSpace.Width / 2) - (iconFont.GetHeight(g) / 4);
         float iconTextYPos = (iconSpace.Height / 2) - (iconFont.GetHeight(g) / 2);
         g.DrawString(iconText, iconFont, iconTextBrush, iconTextXPos, iconTextYPos);

      }

      private GrayBarModes _GrayBarMode = GrayBarModes.GreenTick;
      public GrayBarModes GrayBarMode
      {
         get
         {
            return _GrayBarMode;
         }
         set
         {
            _GrayBarMode = value;
         }
      }

      private string _MessageText;
      public string MessageText
      {
         get
         {
            return _MessageText;
         }
         set
         {
            _MessageText = value;
         }
      }

   }
}

C# | Geeking Out! | UX
Monday, March 26, 2007 9:26:02 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, March 23, 2007

My Pure CSS Tabs with ASP.NET 2.0 Master Pages post also apeared over on CSharpZealot.com where I just added a note about an alternate solution.  Copied here for completeness :)

There was an alternate solution using the CSS Friendly Control Adaptor toolkit for ASPNet 2.0 which renders the standard menu control as UL\LI tags rather than as tables

I chose to not go that route because I don't need the tabs to link to a sitemap datasource or anything cool like that - UL\LI in a master page was plenty good enough for me, however if you did want/need to link the same code to a sitemap then the CSS Friendly adaptors would be well worth looking into.

Listening to:  Wave of Mutilation: The Best of Pixies

Friday, March 23, 2007 11:35:46 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [2]  |