Friday, February 29, 2008

Code - Charles Petzold

If he didn't have a blog, for me Charles Petzold would just be that guy who wrote the seminal book on Windows programming. But since he does have a blog, I now know he's written lots of other stuff as well. I guess that shows blogs can be pretty powerful advertising tools, and I guess I'm not the first person to say so.

Anyway, since I'm regularly reminded of his existence, I'd been thinking of purchasing "Code" for some time (or hoping somebody would buy it for me) and I eventually got round to it. To tell you the truth it wasn't really what I was expecting. Code to me is what I use to write software, but Petzold uses a much wider definition. Code in this book refers to any kind of code from Morse, Braille through telegraphs, onto machine code, ASCII and finally onto programming languages. Although it wasn't what I was expecting I certainly wasn't disappointed. Over the course of the book, Petzold explains why computers are built the way they are, starting from the basic building blocks of relays leading onto transistors, binary numbers and logic gates. This then leads onto more complex circuits finally ending up with a microprocessor. Then he adds to this to finally end up with something resembling the computer we know today.

And all the time, he is explaining why there is the need to build what we are trying to build. For instance, I remember learning abut flip-flops at Uni but I don't remember anybody ever explaining why they are useful (they're a basic form of memory if you're interested). Of course it's quite possible I just wasn't listening when that bit was explained but nevertheless "Code" was a great reminder of the things I've learnt in the past. It also helped to join the dots between different bits of technology.

The book is almost ten years old now, but due to its bias towards the history of computer technology it hasn't dated, unlike most tech books. I guess the final chapter may seem a little out of date but that isn't of major importance.

The only problem I can see with the book is that it may not be suited to non-techy people. There is nothing here that couldn't be understood by a lay-person but it would probably be pretty heavy going. But for a technical person looking for a refresher on the building blocks of computers it is perfect.

Monday, February 18, 2008

Zipping files for Windows Explorer

As part of my automated build process, I wanted to be able to ZIP up files. For this I used the excellent (and free!) ZipLib, but there a few gotchas if you want your generated ZIP files to be readable by the built-in Windows compressed folders functionality.

First, Windows XP doesn't like the Zip64 format used by default so that needs to turned off. Second, Windows doesn't like the full path to be included in the file names inside your ZIP file. This means the easiest to use ZipFile class can't be used. Finally, if you're planning to ZIP up the contents of a directory, make sure you delete any ZIP file that was created previously, otherwise you'll try and ZIP up the already created ZIP file.

All of these caught me out, but this is what I came up with that now seems to work.

      string fileName = Path.Combine(zipFolder, zipFileName);

      // delete the ZIP file if it exists already
      if (File.Exists(fileName))
        File.Delete(fileName);

      DirectoryInfo info = new DirectoryInfo(zipFolder);
      FileInfo[] files = info.GetFiles();

      // zip up the required files
      using (ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(fileName)))
      {
        zipOutputStream.UseZip64 = UseZip64.Off;
        byte[] buffer = new byte[4096];
        for (int i = 0; i < files.Length; i++)
        {
          ZipEntry entry = new ZipEntry(files[i].Name);

          entry.DateTime = DateTime.Now;
          zipOutputStream.PutNextEntry(entry);

          using (FileStream fs = File.OpenRead(files[i].FullName))
          {
            entry.Size = fs.Length;

            int sourceBytes;
            do
            {
              sourceBytes = fs.Read(buffer, 0, buffer.Length);
              zipOutputStream.Write(buffer, 0, sourceBytes);
            }
            while (sourceBytes > 0);
          }
        }

        zipOutputStream.Finish();
        zipOutputStream.Close();
      }

Tuesday, February 12, 2008

Storing variables in a XOML workflow

One problem with XOML only workflows (i.e no code-behind) is the inability to define properties in your top-level workflow to store values that will be used throughout the lifecycle of the workflow, since you haven't got a class in which to define them. Well that's what I thought anyway until I had the idea of creating a custom activity to store these variables. It's all very simple, add the activity to your workflow and set the Value property to whatever you want, then bind it to any other activities that need access to the value.

Here's the code

    public class VariableActivity: Activity
    {
      private string value;
      [Description("The value of the variable")]
      public string Value
      {
        get { return value; }
        set { this.value = value; }
      }
    }

Update - Here's an example of binding the value of the variable to an activity property

<?xml version="1.0" encoding="utf-16"?>
<SequentialWorkflowActivity x:Name="Workflow" xmlns:ns0="clr-namespace:WFBuild.Activities;Assembly=WFBuild.Activities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
  <ns0:VariableActivity x:Name="folderToZip" Value="c:\temp" />
  <ns0:ZipFolderActivity x:Name="zipFolder" Folder="{ActivityBind folderToZip,Path=Value}" />
</SequentialWorkflowActivity>

Sunday, February 10, 2008

Metastorm book

If you've ever wanted to read about Metastorm BPM when you haven't got access to a computer, before now there wasn't really anything available. Now my boss and BPM guru Jerome Pearce has written the 'Metastorm BPM Developer's Guide'. So you can now read all about developing processes when you're sat on the loo.

http://www.lulu.com/content/1862471

Lulu looks like a great website for cheap book publishing, something I hope to be taking advantage of soon. I'll keep you posted.

Friday, February 08, 2008

Who is Edward Phillips?

Over the last few weeks I've noticed a strange thing in iTunes. Occasionally a shared music library will pop up called 'Edward Phillips's Library'. I'm even able to connect to it and listen to music. It's great, he has over 11000 tracks, not all to my taste but still something else to listen to. I did wonder where this new source of music was coming from and tonight I figured it out. I had a look at my router's web interface and noticed a few unknown computers listed in the DHCP active IP table, in fact four computers (although I suspect they aren't all connected right now).

ever since I figured out what was causing our wireless issues I've switched back to an insecure wireless network and I've never bothered to filter out MAC addresses this time around. So it looks like people are taking advantage of the fact. Am I bothered? Not really. I've not noticed any particular performance problems and it seems like my generosity has been repaid by having access to some different music.

On another note, I wonder what the music industry makes of all this? I'm guessing they don't want people sharing out their music collections to all and sundry, we should be good consumers and buy all the CDs instead. But then it's Apple doing this and they make plenty of money for the music industry with their DRM downloads. So perhaps they'll turn a blind eye?

Currently listening to Purple Rain by Prince from the album Purple Rain

Wednesday, February 06, 2008

FeedDemon

I've been using RSS Bandit for many years. I did check out FeedDemon when I was initially looking for an RSS reader, but was put off by the price. Yeh I'm a tight arse, what was it, about $25 or so? But RSS Bandit was free and good enough for my needs. Anyway, when I found out FeedDemon was going to be free, I decided it was time to look at again. And boy am I glad I did.

First, it just works. Whereas RSS Bandit seemed to have a few bugs (the toolbar turning into a big red cross or the app not loading forcing me to delete some XML files) FeedDemon hasn't crashed once. Actually I'd like to see FeedDemon crash, just to see how it handles it (I'm hoping it offers to send the details off so it can be fixed)

Second, it's faster. Yes, I love .NET but real proper compiled Delphi code is always quicker, unless you screw it up, which Nick Bradbury hasn't done.

Third, it has more features. The dinosaur report has been most useful for clearing out feeds I never read.

I have only one request. I signed up for Newsgator for no other reason than I thought this feature would appear (Newsgator serves me no purpose since I'm pretty much always at the same machine) but it didn't. Since Newsgator presumably has a huge database of users and their feeds, I'm guessing it wouldn't be too difficult to suggest new feeds I should subscribe to based on my current feed list. I dunnow, perhaps there are privacy issues around this but I'd sure like to see it available.

Friday, February 01, 2008

Why dynamic languages suck

I had a little bit of JScript that wasn't working as expected. I stared and stared at it... For a very long time... Here it is.

var splitDetails = details.split("\t");
for (var i=0; i<splitDetails.Length; i++)
{
  // do something
} 

The problem was that the //do something was never getting hit. Life would have been easier with a debugger but this was server-side JScript in Metastorm which doesn't support debugging so I was forced to just stare at it to work out what was wrong.

No doubt you're now shouting at your computer "you're a fecking idiot! The problem is obvious!" and perhaps you'd be right. Perhaps I was just having a senior moment, which I think I'm entitled to have at my age. For those of you who haven't spotted the error I'd typed length with an upper-case L.

So what happens here? JScript doesn't throw an error because I've tried to access a property that doesn't exist, instead it returns null. Then I presume it converts that to 0 for the loop test so never drops into the code inside the loop.

This kind of thing is all too easy in a dynamic language. If I was using a compiled statically-typed language the compiler would have picked up the problem immediately. Perhaps the advantages of dynamic languages outweigh these kind of problems but personally I'd rather have the crutch of a compiler.