Mad Props!

Omniscience is just a Google-search away.

Login

You're reading Mabsterama, the weblog of Matt Hamilton. Enjoy your stay.

SecretZip

I listened (finally) to last week's Hanselminutes featuring SecretGeek's Leon Bambrick. Leon talked about the steps involved in becoming a "Micro-ISV" - that is, an independent software vendor on a small scale (with one or two commercial products). He's following up his appearance on the show with a series of blog posts detailing each step.

Anyway, at one point Scott and Leon were talking about shareware, and how so many people never bother registering and paying for their software. The example that Leon posited was WinZip, to which Scott replied, "And who doesn't use WinZip?" I actually raised my hand, sitting alone in my car on the way to work, and I was pleasantly surprised when Leon, too, admitted that he doesn't use WinZip, instead relying on the inbuilt support for zip compression in Windows.

WinZip was a great little tool in its day, but there are only a few reasons that I can think of for having it installed once you're running Windows XP:

  • Support for compression formats other than zip
  • Password-protected zip files
  • Self-extracting (executable) zip files

If any of those reasons apply to you, then yes, you probably need (and should pay for) WinZip. Otherwise, why bother?

Google Image Search Revamped

Damn! Euan just pointed out that our "grabimg" utility here on Mad Props no longer works. We coded up a small ASP.NET utility a few years ago which, given a single parameter, would perform an image search on Google and return a random thumbnail from the results. It made decorating our blog posts easy, since we'd be able to insert some HTML like <img src="/grabimg?image=vista" mce_src="/grabimg?image=vista"> and a random image of Vista would be inserted.

Well, it has stopped working in the past few days because Google have changed the way they display the search results on their image search page. Instead of plain old HTML, they're now using javascript and rendering the thumbnails dynamically. It's more or less impossible for us to predictably scrape the results.

That's a real shame. If anyone knows of an "open" image search site that we might be able to use in place of Google, let me know!

Menus and Toolbars

This post is inspired by my recent attempts to educate mum and dad in the use of the various tools with which we access the Internet. My folks are very non-technical. Dad knows how to launch iTunes (and I managed to teach him how to rip a CD, which was a monumental achievement), and mum knows how to poke around in Picasa to view her photos.

Microsoft, as I've mentioned earlier, are starting to shy away from the classic "main menu" user interface. I've used five of their recently-released products that have done away with the main menu:

The problem is, only two of these five have replaced the main menu with anything usable:

  • Office 2007 introduced the ribbon, which puts every single available command right in your face.
  • Internet Explorer 7 moved most (all?) of the commands you need to dropdown menus underneath a few toolbar buttons (Page, Tools and Help), as well as introducing the "Favorites Center" to manage all your bookmarks.

The other three applications have surfaced only a tiny subset of the available commands to the toolbar, and relegated the rest of them to a "hidden" main menu, which you access either by hitting "Alt" or by finding an obscurely-placed "menu button" somewhere on the window. In the case of Windows Live Messenger this button is in the non-client area of the window, making it even more difficult to find.

So now if you want to change the options for your program, you have to locate this button, drop down the resulting menu, and select "Tools|Options". It may only be one more click, but the fact that the entire menu hierarchy is hidden under this button means that Joe User simply isn't going to find it.

When I installed Windows Live Messenger on mum and dad's PC, I immediately opened the options and turned off some of the more annoying default settings. For example, the "Open Windows  Live Messenger main window when Windows Live Messenger starts" and "Show Windows Live Today after signing in to Messenger". There is zero percent chance that my mum and dad would have discovered how to do this on their own.

Windows Live Mail Desktop is no better. Want to change how often it checks for new mail? Good luck. Again, you have to first locate the button to show the main menu (or know that the Alt key does the same, except don't hold the Alt key down - you have to tap it), then click "Tools|Options". For mum and dad, the options dialog here also has a zero percent chance of being discovered.

Obviously these new user interfaces are targetted at two types of users: Power-users like me who know where to look for the extra commands, and end-users who are happy with the defaults. I would guess that these two groups account for half of all computer users. That's not a good hit ratio if you're trying to make easy-to-use software.

I applaud MS for trying to innovate in the UI space. I don't mind them dropping the main menus from their applications. But for the love of god, don't bury 90% of the available commands under some hidden button! Give us easily-discoverable options! Your users will thank you for it.

Binding to Nested Properties

My workmate Vijay is playing with WCF with a small project, and was asking me how to display a "nested" property of his business object in a DataGridView. I'll walk through an example here, changing the class names to protect the innocent.

Let's say you have a collection of characters and the movies they appeared in. Let's say the classes look like this:

class Studio
{
    public String Name { /* ... */ } 
    /* ... */  
} 

class Movie 
{ 
    public String Name { /* ... */ }  
    public Studio Studio { /* ... */ } 
    /* ... */  
} 

class Character  
{ 
    public String Name { /* ... */ } 
    public Movie Movie { /* ... */ } 
}

You want to display them in a grid, like this:

Character Movie Studio
Chief Brody Jaws Universal
Han Solo Star Wars 20th Century Fox

So you've bound your DataGridView to your list of characters (maybe it's a BindingList<Character> collection) and added some columns. The first column's easy - it's just bound to the "Name" property of the "Character" class. What about the next column? Bind it to the "Movie" property and run your app and you'll see something like this:

Character Movie
Chief Brody WindowsApplication1.Movie
Han Solo WindowsApplication1.Movie

That doesn't look right. What has happened? The DataGridView only knows that the second column is bound to a property of type "Movie", and it has no idea how to represent a "Movie" object on screen. You need to tell it that you would like to see the name of the movie. An easy way to do this is to handle the CellFormatting event of the grid, like this:

private void dataGridView1_CellFormatting(object sender, 
    DataGridViewCellFormattingEventArgs e) 
{ 
    if (e.Value is Movie) 
    { 
        e.Value = (e.Value as Movie).Name; 
    } 
}

See what's happening there? We're looking for a cell whose value is of type "Movie", and we're replacing its content with the name of the movie in question. Rerun, and our grid looks better:

Character Movie
Chief Brody Jaws
Han Solo Star Wars

So now we need to get the "Studio" column in there. We add a new column, and bind to ... what? "Movie.Studio"? That doesn't work. How the heck can we show the studio in the grid?

If we had control over the "Character" class, the easiest solution would be to add a "Studio" property to the class itself. However, in this scenario we're talking about objects returned from a service, and it might be one we didn't write. We can't just go changing the definition of "Character"! Or ... can we?

The beauty of the classes generated by Visual Studio when you add a "web reference" or "service reference" is that they're partial classes. You have the ability to extend them by defining the "other half" of the partial class. This is exactly the way Windows Forms work in .NET - the "designer" part of the form (the generated code that creates and places controls) is one half of a partial class, and your code is the other half.

So we can add to the structure of a class that's returned from a service. Let's add a "Studio" property to the "Character" class! First we'll add a new file to our project, and call it Character.cs. Next, we have to make sure we're defining this partial class in the correct namespace - otherwise the compiler will have no idea that it's the "other half" of an existing code. For this example I'll assume that the "Character" class was generated in a service reference called CharServiceRef.

namespace WindowsApplication1.CharServiceRef 
{ 
    public partial class Character  
    { 
        public Studio Studio 
        { 
            get { return this.Movie.Studio; } 
        } 
    } 
} 

This is a very simple read-only property that returns the studio of the character's movie. Now we can add a column to our grid that is bound to the "Studio" property, and adjust our CellFormatting event handler thusly:

private void dataGridView1_CellFormatting(object sender, 
    DataGridViewCellFormattingEventArgs e) 
{ 
    if (e.Value is Movie)
    {
        e.Value = (e.Value as Movie).Name;
    }
    else if (e.Value is Studio)
    {
        e.Value = (e.Value as Studio).Name; 
    }
}

Et voila! Now your grid can display the nested property ("Studio") and looks just like our original example:

Character Movie Studio
Chief Brody Jaws Universal
Han Solo Star Wars 20th Century Fox

The ability to extend types that you didn't define through the use of partial classes is an invaluable piece of the "service oriented" puzzle. This is just one small use for this feature. There are plenty of others! Go forth and extend!

Windows Live Mail Desktop (Beta)

Over the past few days I've been playing with the latest beta of Windows Live Mail Desktop. WLMd is essentially the successor to Outlook Express, in that it's a small email and usenet client. In addition to mail and news, however, WLMd also handles your RSS feeds, and presents them to you in a "mail-like" fashion.

For many years at home now I've been using Mozilla Thunderbird as my mail and news client. It's pretty slick, and I would have no trouble recommending it to a friend or to a friend's mum and dad. However, I saw no harm in checking out Microsoft's latest offering.

My thoughts so far, then. The good:

  • The "active search" feature is very nice. Simply start typing and your current view is filtered down according to the text you've typed. This is very handy if you're searching for something you caught in a blog post a while back, but is now buried deep within your feeds.
  • Making use of this search functionality are the "search folders", which are like views on your data. An example is the "unread mail" folder, which shows all of your unread mail from across all the accounts you've set up. That's quite cool.
  • Integration with the other Live products is pretty tight. If the person you just received an email from is in your instant messaging address book, you can reply instantly with Windows Live Messenger. If you'd like to publish an email message or feed article to your blog, you can pop it open in Windows Live Writer. Very nice.

The bad:

  • The 'reading pane' (or preview pane, if you like) can be either to the right of or below your message list, but you can't customize that on a per-folder basis. I would love to have the preview pane to the right of my email inbox but beneath my RSS feed list, but that's not possible.
  • There's a skyscraper ad taking up about 80 pixels of real estate at the right side of the window. Considering Microsoft are pushing the "horizontal" layout (folders | messages | reading pane), this takes up a lot of valuable space and makes the window feel very cramped.

The rest:

  • The keyboard shortcuts are hard to get used to. This isn't really a slight on the product, but I'm so used to being able to hit "n" in Thunderbird to get to the next unread message that hitting "Ctrl+U" feels really cumbersome.
  • Junk (spam) mail handling is very good, except there's no way to mark a messages as junk from within a search folder. Since you're likely to spend most of your time in the "unread mail" folder, that makes it very awkward to flag a spam message. You have to switch back to the relevant inbox, locate the message, and then hit the Junk button (or press Ctrl+J).
  • RSS feeds with Simple List Extensions (SLE) don't seem to work at all.
  • Program options are difficult to find (the main menu is tucked away under a menu button similar to Windows Media Player). I wanted to modify how often the program checks for new mail (the default is 30 minutes), and had to hunt around for that menu button, then click Tools, then Options. I know that Microsoft seem to be shying away from the old "main menu" style, but the common options should be a little more accessible.
  • I still don't know how this program fits in with/competes with Windows Mail - the mail client that ships as part of Windows Vista.
  • Perhaps the biggest obstacle to getting mums and dads into this program: It requires a Windows Live ID (ie Passport or Hotmail address) to run. You can add any old email account you like once you're in, but to get in you need to sign in using your Live ID. I assume that this has something to do with presence awareness and synchronizing of your address book, but it seems unnecessary.

I'll continue using WLMd as my default email program at home for the rest of the week, and see whether it's worth switching over permanently. I'm also evaluating it on behalf of my own parents, who will (finally) be online in a week or two. We'll see whether it beats out Thunderbird in the race to the folks' desktop.

Death to the Drive Letter

One of the most interesting, and most welcome, features of the recently-announced Windows Home Server is that it no longer uses drive letters. As you add storage (in the form of USB, ATA or SATA drives) they are simply added to a common pool of storage used by the OS.

Drive letters are an artifact of older operating systems, dating way back to (and before) the first versions of DOS. You can read a bit of a history of drive letters on Wikipedia here.

Today, most users know that "C" drive is their system disk, and that "D" drive is either a second hard drive, or an optical drive of some sort (CDROM, DVDROM etc). Further to that, there may be extra drive letters for attached devices such as USB hard drives or digital cameras.

Floppy DiskThe letters before "C" in the drive line-ups are more historical and less relevant than ever. Most modern machines don't even come with a fixed floppy drive, and hence don't have an "A" drive at all. Some of the first PCs I used had both a 5.25" and a 3.5" drive, allocated to "A" and "B" respectively. Later, the 3.5" drive became "A", and "B" was relegated to "virtual" status, mirroring "A" and useful only in copying floppies.

The idea of simply pooling data from multiple drives into a shared storage resource is something rather new to Windows. In the various unix flavours out there you "mount" new drives under a root folder (eg the "/usr" directory might be a completely separate disk from the "/bin" directory). This system still has limitations - run out of space on the disk allocated for "/usr" and you're in some trouble.

Windows Home ServerWindows Home Server takes a new approach - it mirrors anything and everything across more than one disk. If one drive were to fail, you know that you have a good copy of all data on the disk somewhere else. At a convenient time you can simply yank the faulty disk and insert a new one, and the mirrors are rebuilt accordingly.

This approach does have one obvious caveat: You have less disk space to play with, because everything's stored twice. WHS compensates for that by storing only one copy of each unique file from all the machines you're backing up, so the more PCs you're backing up, the better use of space you'll have. This is great for a shared backup device, but less useful if you're trying to use this shared storage pool as a single-machine resource.

My feeling, though, is that eventually it won't matter. Hard drive space is so cheap nowadays that it won't be too big an issue to buy two disks instead of one if you're worried about hardware faults. Ideally, a future version of WIndows that could make use of this technology would be smart enough to mirror the user's data, but not the system files or installed programs. After all, you can always reinstall a program, but I'm guessing you'd rather not retype that thesis.

So here's a call to arms (and I know it's not the first): Death to the drive letter! With any luck the next generations will only ever see a "C:" in the history books.

AWDNUG January Meeting

The first meeting for 2007 of the Albury/Wodonga .NET User Group has just wrapped up, and as you may recall this month's meeting was all about Comicster.

I must admit that I was packing death before the meeting - nervous almost to the point of hyperventilation. I needn't have been - everyone at the group is really helpful and genuinely interested in what the presenter(s) have to say, so there's never any pressure. This month's meeting was no exception - everyone was keenly interested in Comicster, and the questions and discussions were very insightful.

Next month we'll be looking at SharePoint, which should be really interesting. Pablo from Albury TAFE will be giving us a rundown on how to install it, and we might even get a glimpse at the TAFE's own SharePoint-driven intranet, which would be of great value for some of us looking to implement corporate intranets of our own.

See you there, fellow border residents!!!

Automatically Tidying Your Feeds!

In my last post I described a way to list out all your subscribed feeds that haven't been posted to in four months. This works well, but leaves it up to you to do something with those feeds.

The next logical step is to let PowerShell worry about them. That is, have the script itself automatically delete the feeds, or perhaps move them to a "Dead" folder for you to keep an eye on.

Now, the current version the PowerShell Community Extensions does not have a FeedStoreProvider that supports the "move-item" command, but that'll change soon (I've already written the code). In the meantime, here's how you'd delete the old feeds:

cd feed:\
gci -rec |
   ?{ $_.Type -eq "Feed" } |
   %{ $_.Items | sort -desc PubDate | select -first 1 } |
   ?{ $_.PubDate -lt [DateTime]::Now.AddMonths(-4) -and $_.PubDate.Year -gt 1899} |
   %{ $_.Parent } |
   remove-item -recurse 

Note the "-recurse" parameter on remove-item. That's because feeds are technically containers (they contain feed items), so unless you specify the "-recurse" parameter you will be prompted to delete each feed.

Next, here's how you'd move the old feeds to a "Dead" folder:

cd feed:\
new-item -itemType Folder Dead
gci -rec |
   ?{ $_.Type -eq "Feed" } |
   %{ $_.Items |  sort -desc PubDate | select -first 1 } |
   ?{ $_.PubDate -lt [DateTime]::Now.AddMonths(-4) -and $_.PubDate.Year -gt 1899} |
   %{ $_.Parent } |
   move-item -destination \Dead 

One small caveat: You have to be sitting in the root of your "feed:" drive for this to work. The reason for this is that remove-item and move-item both look for a "Path" property on the item that gets piped through to them, and for feeds the "Path" property is a relative path from the root folder (eg. "Blogs\Mabsterama"). So the commands won't find the item to remove or move unless you're currently sitting in "feed:\".

Tidy Those Feeds!

With the new year well and truly underway, it's time to go over all those RSS feeds you're subscribed to, and clean out the ones that don't get updated any more.

But how? How could you possibly know which feeds haven't been posted to in the past, say, four months?

Why - with Windows PowerShell, of course! With a little help from the PowerShell Community Extensions and its awesome Common Feed Store provider!

So here's the command:

gci feed:\ -rec | ?{ $_.Type -eq "Feed" } | %{ $_.Items | sort -desc PubDate | select -first 1 } | ?{ $_.PubDate -lt [DateTime]::Now.AddMonths(-4)} | select @{Name="Feed"; Expression={$_.Parent.Name}}, PubDate | ft -au 

... and here's the result on my home PC:

Feed PubDate ---- ------- DataWorks WebLog 12/07/2006 7:57:00 AM Smart Client Data 9/08/2006 8:10:00 PM What's in Store 27/06/2006 1:26:00 PM Mick's Mix 21/08/2006 9:07:00 PM Microsoft at Home 20/06/2006 6:00:00 PM Microsoft at Work 9/05/2006 6:00:00 PM Xbox World Australia 30/12/1899 12:00:00 AM DVD Plaza 30/12/1899 12:00:00 AM Luke Hutteman 9/01/2006 5:12:37 AM Microsoft at Home 20/06/2006 6:00:00 PM Microsoft at Work 9/05/2006 6:00:00 PM 

Notice that a couple of those feeds have a date in 1899. That means that they don't provide a date against their posts, so they can be ignored - might as well keep hold of 'em. The rest can go! Ah ... a fresh start. :)

Windows Home Server

HP MediaSmart Server powered by Windows Home Server

Bill Gates just wrapped up his keynote at CES, and for me the most interesting announcement was that of Windows Home Server.

The idea is that you install WHS on a relatively low-end PC (the minimum specs are a 1GHz CPU and 512MB of RAM), and plonk it in a cupboard at home. It doesn't need a monitor or keyboard - it's a "headless" OS.

You then install some client software on every PC on your network, and ... forget about it.

Every night, WHS will seek out the PCs connected to your home network, and back them up. It takes complete image backups of every PC, and gives you the ability to browse for individual files, or to do an image-based restore if you simply want to put a PC back the way it was at a given time. Backups are mirrored across disks, so if you lose a drive in your server you won't lose any files.

It also supports access to media from your Xbox 360, so you can stream pictures, music and video directly from it.

On top of that, it enables you to get access to your files securely from anywhere on the Internet. Obviously making use of the technology Microsoft acquired from FolderShare a while back. FolderShare is a great little product for synchronizing folders between multiple PCs, and accessing files over an encrypted Internet connection.

Considering you can build up a 1.5TB (yes, TB) machine for around AU$1200 nowadays ... this is a pretty compelling solution. Never have to worry about backups again. Ever.

Further reading:

ps. I wonder if this can actually back up your Xbox 360's hard drive? That would certainly solve the problem of migrating save games from one drive to another etc!