November 2009 Blog Posts

Nothing Says Thanksgiving Like People Getting Their Asses Kicked

Thanksgiving is my least favorite holiday.

I don't like turkey. (Yes, it's OK to gasp at that, and I know it's hard to believe, but I'm not the only person out there who doesn't like turkey.) I don't like most of the trimmings that go along with a traditional Thanksgiving dinner. Stuffing? No thanks. I've even been talked about on the How Stuff Works podcast during "Listener Mail" time because of my turkey loathing. I usually end up in one of two situations, neither of which are good:

  1. Eat only mashed potatoes and rolls for dinner. Maybe sweet potatoes if there are some, but generally, the potatoes and rolls are the only bits of the traditional Thanksgiving dinner that are remotely palatable to me. This isn't a good dinner and it's not super tasty.
  2. Eat a one-off meal totally different from everyone else. This is bad in a different way. It means I'm eating something I like, but it also means I get to - yet again, and many times to the same people - explain why I'm eating something different. Not just a pain in the ass, but psychologically troubling as I get the looks and questions from around the table.

The last few years my family and I have gone to a buffet for Thanksgiving so they can have their turkey, but there are plenty of other things to eat and no one really notices because, well, it's a buffet. This year, due to some scheduling trouble and other circumstances, that didn't happen and it would have ended up being one of the above two situations. Again. I'm tired of that, so this year Jenn and I got together with a couple of friends... and some friends of friends... and their families... and had dinner with them.

While I am grateful to have met some very nice new friends and have been invited into their home for a meal of tasty shrimp scampi... it ended up being scenario #2 as mentioned above, which is not quite what I thought I was getting into. Again, no reflection on our friends, as they were wonderful and hospitable.

I think next year I'm just boycotting the whole Thanksgiving thing. It would be different if my family lived more than about 45 minutes away and I didn't see them all the time, but they do, and I do, so the only real value Thanksgiving has is the dinner, which is the bit I'm not interested in.

The holiday weekend got a little better when we went to see Ninja Assassin. Great fight scenes and a little over-the-top gore never hurt anyone. It was only OK, as I wish the actual plot bits didn't seem so... flat... but it was fun and nothing says 'Thanksgiving' like people getting their asses kicked.

The rest of the long weekend was spent playing a little Xbox 360, getting stuff done around the house, and generally relaxing, which always makes for a nice time. It looks like next weekend we'll be decorating the house for Christmas, which should be fun.

Filing Music: Dealing with Artist Names

A few days ago I was listening to some music on my iPod and noticed that a couple of tracks had metadata filed as "Firstname Lastname," which is not how I file my music. I think I picked them up off AmazonMP3, and it kind of irritated me that I had to fix it, so I tweeted:

Wondering why so many folks file their music "Firstname Lastname" instead of "Lastname, Firstname."

That actually brought a lot of responses (more than some questions I have where I actually really need to know the answer). I got a couple of responses from folks who wondered the same thing, but the opposition to the idea cited basically two problems:

  1. Most metadata out there is stored this way so it's easier to just use it as-is than it is to fix it for your own collection.
  2. There could be confusion if you have a solo artist who also has a band. For example, "Ben Folds" should show up by "Ben Folds Five" if you have music by both.

My logic in storing "Lastname, Firstname" is pretty simple.

  • When I go looking in the store (or at the library) for "Michael Jackson," I don't go looking under "M." I don't think that should be different on my iPod.
  • I have no desire to store separate "display data" and "sort data," though that possibility exists. Doing it that way means double-metadata to manage and makes the list look messy.

I looked around at how libraries file things and, while I couldn't get my hands on a copy of the Library of Congress filing rules I did gather that, generally speaking, the accepted convention for Folks Who File For a Living is:

  • If it's an individual person: Lastname, Firstname (e.g., "Folds, Ben")
  • If it's a collective, corporation, or group: Firstname Lastname (e.g., "Ben Folds Five" or "Steve Miller Band")

That's actually how I have my music filed, and that makes sense to me. I contacted a good friend of mine who actually went to school for this stuff and he concurred. He also mentioned that there are interesting edge cases to consider - for example, "Alice Cooper" was not originally the name of the singer but the name of the band, so you could argue it either way.

That would, in fact, mean you would not normally see solo work by Ben Folds sitting alongside his group work in Ben Folds Five, and you'd see Dave Matthews Band under "D" not "M," but if Dave Matthews had solo work, it'd be under "M."

My friend pointed me to DMOZ, the Open Directory Project, which is a place some folks feel is a good starting place to look if you don't know how something would be filed. This general premise - individuals as Lastname, Firstname and groups as Firstname Lastname - appears to hold there.

Of course, I see why online music stores chose to skip this - so there are no edge cases. Trade potentially "incorrect" metadata to avoid forum flame wars about why individual artists don't appear right next to their bands and such. I guess I'll just have to continue fixing it manually.

Now to figure out the best way to store artist collaborations - duets, for example. If only there were multiple artist fields in the ID3 spec. Oh, wait, ID3 does support that. Too bad iTunes doesn't. (Yeah, I know, MP4 doesn't directly support ID3 but atoms... I still think it's possible to support multiple artists.)

Becoming Festive

The holiday season has begun at home, preceded quite a bit by its start in the stores. (Stores very nearly skipped Halloween this year and went straight to Christmas, didn't they?)

First, we got a wreath for our door from a local door-to-door salesgirl. This is important in two respects: First, I've never had a wreath before, and while it sounds sort of cliché, it's nice and sort of makes me feel like "a real homeowner" (even though we've been at the same place for years now). Second, if your kid gets off their ass and actually does the door-to-door sales for their organization, I'll most likely buy something; if you take the sign-up sheet to work and stick it on the break area table and expect me to register... well, good luck with that. Hard work gets rewarded.

2009 Trans-Siberian Orchestra

Second, we went to the Trans-Siberian Orchestra concert on Sunday. Not the first time we've seen them, but a brilliant show. Everything with TSO is always larger-than-life. Every number is huge and that just makes it full of awesome. We were in the tenth row, center section on the aisle - perfect seats. I snuck a few pictures toward the end with my crappy Blackberry camera. Epic stuff. I'd totally go again.

This week is Thanksgiving and I totally can't stand turkey, nor am I really big on attempting to coordinate a bajillion disparate schedules to make sure everyone gets their "face time" in, which makes it my least favorite holiday all year. (I think it'd be more important to get together with people if we all didn't live within 45 minutes of each other and see each other all the time.)

But I'm not going to let that drag me down. I've got this free-standing two-foot-tall green M&M in a Santa hat to stick by our front door and I've been waiting to put her out. Onward to the holidays!

Putting log4net.config Outside of Application Configuration

I use log4net for logging in various applications, but every time I start a new app I forget this and it never quite comes up in Google for me, so here we go.

Most of the examples on the log4net site showing configuration shows it right in the App.config/Web.config file for the application. That's a painful way to go if you have, say, a single log4net.config that you want used in several projects or if you otherwise want to stick log4net.config somewhere else.

The magic bit that at least I can't easily find and always forget is:

If you add an appSettings key called "log4net.Config" you can put an app-relative path to an external log4net.config file in there and everything will automatically configure itself using that.

It looks like this:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="log4net.Config" value="log4net.config" />
  </appSettings>
</configuration>

That example puts the log4net.config file right in the root of the application. You could specify "config/log4net.config" to put it in a "config" subfolder, too, for example. You don't even have to call the XmlConfigurator.Configure method or mark your assembly with an XmlConfiguratorAttribute or anything. Magic happens. It just works.

This is specifically for the default "log4net-default-repository" repository. If you're doing something fancy with different repositories, YMMV. I've not tried that.

For folks interested in spelunking, this is a hardcoded setting that takes effect in the private log4net.Core.DefaultRepositorySelector.ConfigureRepository(Assembly, ILoggerRepository) method which gets called from the public log4net.Core.DefaultRepositorySelector.CreateRepository(Assembly, Type, String, Boolean) method.

Fixing the Weird One-Pixel Line in Windows Media Center

In both Vista and Windows 7, when running at full 1920 x 1080 resolution, I found that I would occasionally see a one or two pixel "line" along the right side of my TV when playing video. It looked like some sort of artifact left from the menu I was just using to select the video, but I couldn't tell. I started down the road of trying to figure out if I needed to tweak some overscan setting or something when I posted to The Green Button forums to see if anyone else saw this.

Turns out there's a hotfix for this specific issue.

KB 974324: "Black and white pixels unexpectedly appear on the right side of the screen when you run Windows Media Center in full-screen mode in Windows 7 or in Windows Vista."

Downloaded and installed the hotfix, problem solved. If you're seeing this problem, grab the hotfix.

Context Menu Icons with DXCore

A long time ago I posted a little sample showing how to get context menus working with your DXCore plugin. As part of a new plugin I'm working on, I wanted to get an icon to show up in the context menu next to my entry in the menu, something like the icon you see for the Refactor! menu:

Context menu in Visual Studio showing the Refactor! icon.

It's possible, but it's not really documented, so here's what you do.

First, make sure you're working with a DevExpress.CodeRush.Menus.IMenuButton. This is the type of thing you can click on and have something happen, as opposed to a DevExpress.CodeRush.Menus.IMenuPopup which is what allows you to have nested menus (like if you hover over it another context menu will fly out). The IMenuButton can have an icon, the IMenuPopup can't.

Now make two 32 x 32 bitmap images. The first is going to be the icon you want to display. The second is the transparency mask so the menu knows what to show and what to hide. They will look something like this:

The color image:

Color version of the button.

The transparency mask:

The icon transparency mask.

Note that in the transparency mask, the black pixels are the parts of the image I want shown and the white pixels are parts I want to be transparent.

To make it easy, I used the Visual Studio icon editor. You could do this in your favorite paint program or whatever, but I'm lazy. This has the added benefit of embedding the icons as resources (which, again, you could do after creating these in a paint program).

Once you have your icon and your transparency mask, you can create your button, set the style to show both the icon and the caption (text), then call SetFace() to set the "Face" property to be the color icon and the "Mask" to be the transparency mask. It'll look something like this:

MenuBar editorContextMenu = DevExpress.CodeRush.VSCore.Manager.Menus.Bars[VsCommonBar.EditorContext];
var contextMenuButton = editorContextMenu.AddButton();
contextMenuButton.Style = ButtonStyle.IconAndCaption;
contextMenuButton.SetFace(
Properties.Resources.ContextButtonIcon.ToBitmap(),
Properties.Resources.ContextButtonIconMask.ToBitmap());
// ...and set other properties, too:
// * Caption
// * Enabled
// * Click event handler
// * etc.

Note the "ToBitmap()" call I have there - that's because the "Face" and "Mask" properties take bitmaps but I used the icon editor so the format needs to be transformed into a bitmap from an icon. If you embed a bitmap directly, you won't have to do anything additional.

Once you have that, your button should have the proper icon with transparency in the context menu. Done!

New button on the context menu, complete with icon.

UPDATE 3/4/2010: Rather than setting "Face" and "Mask" separately, use the "SetFace" method. Setting the properties manually works in VS2008 but fails in VS2010; using "SetFace" works in both.

Windows 7 Supported Audio/Video Formats

In researching potential video formats for switching my DVD library from VIDEO_TS to something else (due to file access time issues) I found I had real trouble locating the list of audio and video formats that Windows 7 supports out of the box. The provided "supported formats" page really isn't technical enough.

While I haven't determined which video format to move my library to, I did get a response to my question about this on the forums. Here's the info from there, for your convenience:

Format Name File Extensions Container Video Decoders Audio Decoders
MPEG-4 .mp4 (A, V, A+V)
.m4a (A)
.mov
ISO MPEG-4, AVI H.264, MPEG-4 Advanced Simple Profile (ASP) and Simple Profile (SP) AAC, MP3
3GPP/3GPP2 .3gp, .3g2
(A, V, A+V)
3GP H.264, MPEG-4 Simple Profile (SP) AAC
AAC .aac (A)

ADTS

  AAC
ASP in AVI (Compatible with DivX 4-6 video, Xvid and 3ivx) .avi (V, A+V) AVI MPEG-4 Advanced Simple Profile (ASP) MP3, MS ADPCM
AVCHD .m2t, m2ts, .mts (A, V, A+V) MPEG-2 Transport Stream (TS) H.264 Dolby Digital, LPCM
HDV .m2t, m2ts, .mts (A, V, A+V) MPEG-2 Transport Stream (TS) MPEG-2

MPEG-1 L2 (Layer 2)

Or, split/arranged a different way:

Category Supported Types
Video Decoders
  • H.264/AVC Baseline, Main and High Profiles (new in Windows 7)
  • MPEG-4 Advanced Simple Profile (new in Windows 7) besides Simple Profile
  • Subset of H.263 that overlaps with MPEG-4 SP
  • Motion JPEG (new in Windows 7)
  • WMV variants including VC1 and WMV Screen
  • MPEG-1 and -2
  • DV
Audio Decoders
  • AAC, HE-AAC, HE-AAC v2 (new in Windows 7)
  • Dolby Digital Plus (new in Windows 7) besides Dolby Digital/AC-3
  • WMA family of music decoders and speech decoders
  • MP3
  • MPEG-1 and -2
Image Decoders
  • HD Photo (JPEG-XR)
  • JPEG
  • PNG
  • BMP
  • TIFF
  • GIF
  • ICO (Icon Format)
Containers
  • MP4 and its close cousins MOV, 3GP, M4A (new in Windows 7)
  • Media Center's WTV (new in Win7 and Media Center TV Pack) and DVR-MS
  • MPEG-2 Transport Streams and its cousin AVCHD
  • MPEG-1 and -2 Program Streams
  • AVI, WAV
  • ASF
  • DVD
  • ADTS

Debugging Visual Studio Add-Ins and XmlSerialization Problems

The quick version:

If you're writing a Visual Studio add-in, a DXCore add-in, or anything else where the debug environment is Visual Studio itself, be careful not to load the add-in project in the Visual Studio instance you're debugging. You'll get some weird errors.

This is a total edge case but it had me baffled for a while.

I'm working on a DXCore plugin that talks to a web service. It takes some selected code and sends it to a web service to do something with. Since you need code to work with, the easiest way to debug it was to:

  1. Hit F5 to start another Visual Studio environment with the add-in installed.
  2. Go to File -> Recent Projects and grab the first one in the list - the add-in project.
  3. Test out the plugin.

At one point I made a call to the web service using a complex type (not a string or integer, but a data transfer object) like this:

ComplexObject response = serviceProxy.DoAnOperation(param1, param2);

...where param1 is an input object of type ComplexObject. Doing that I got a weird XmlSerializationException:

[A]CR_PluginName.WebServiceNamespace.ComplexObject cannot be cast to [B]CR_PluginName.WebServiceNamespace.ComplexObject. Type A originates from 'CR_PluginName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadFrom' at location 'C:\Documents and Settings\tillig\My Documents\DevExpress\IDE Tools\Community\PlugIns\CR_PluginName.dll'. Type B originates from 'CR_PluginName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' at location 'C:\Documents and Settings\tillig\Local Settings\Application Data\Microsoft\VisualStudio\9.0\ProjectAssemblies\wi3h64z601\CR_PluginName.dll'.

Huh?

The key was in the second location: "...\ProjectAssemblies\..." The object I was sending to the web service was defined in the plugin assembly... but it was trying to deserialize the response using the temporary assembly that the debug instance of Visual Studio had compiled in the background.

The solution ends up being "don't do that." Opening up a different solution, I no longer had issues debugging my web service calls and the plugin worked fine.

  1. Hit F5 to start another Visual Studio environment with the add-in installed.
  2. Go to File -> Open Project... and find some other project that is not the add-in project.
  3. Test out the plugin.

How to Upgrade PerfectDisk for Windows Home Server

UPDATE 11/4/2009: I got some feedback on this process from Raxco (PerfectDisk) Support. They say:

The update process is as follows:

  • While connected to your WHS and notified than an update to PD is available, choose Install
  • When notified that the Console is open and prompted to Retry, Ignore or Cancel, choose Ignore
  • When update has finished and prompted to reboot your WHS, reboot
  • Upon reboot of your WHS, PD should be updated.

Note that if you run PD and click on Product Resources, PD shows that it has been updated to new build. If you look in the add-ins, it still says that old PD build is installed. This is due to the way that the add-in manager is looking to see what is installed/available - it is not looking in the "normal" locations to determine what is actually installed - it is using a different set of registry keys. Also note that if you have HP WHS, after updating to a new build of PD, the Network Critical tab displaying PD update as available even though it is already installed. This is something specific to HP WHS and we are currently waiting to hear from HP on what exactly they are checking/doing.

I'm not so sure I like that there are "expected problems" remaining after this upgrade process. Doing it my way, you get the upgrade, the version reads correctly, and there's no remaining WHS "Network Critical" warning. For reference, the original entry I wrote and the process I followed for upgrade is here...


I've got PerfectDisk for Windows Home Server installed and I generally like it but the installation procedure is a little weird.

A fresh install goes like this:

  1. Download the full installation package for PerfectDisk to your client computer.
  2. Install PerfectDisk on your client computer.
  3. As part of the installation, a folder will be created where the PerfectDisk add-in for Windows Home Server will be placed. The location is typically something like: C:\Program Files\Raxco\PerfectDisk10Install\PerfectDisk10_Home_Server\PerfectDisk_x86.msi
  4. Drop the PerfectDisk_x86.msi file into the \\server\software\add-ins folder on your Windows Home Server.
  5. Open the Windows Home Server console, go to the "Settings" tab, and under "Add-Ins" select to install the PerfectDisk add-in.

The last few steps - dropping the installer in the "add-ins" folder, opening the WHS console, and installing add-in - is pretty standard WHS stuff. The weird bit is that you can't just get the WHS add-in as a direct download - you have to install on a client computer.

Recently I found there was an upgrade to PerfectDisk and the upgrade process isn't documented. This is what the process is from what I can tell, after some panicking and manually uninstalling things.

PerfectDisk has a feature to "check for updates" from within the Windows Home Server console. It's OK to use the "check for updates" feature to see if there's an update, but do not install the update from there.

First, trying that will fail because the Windows Home Server console is open (Catch-22, eh?). Second, if you try to do the update from Windows Home Server via Terminal Services, it doesn't quite do what you expect. I think the engine gets updated, but the console add-in doesn't or something. Stuff gets messed up. Just don't do it.

Instead, it appears that this is the proper sequence of events for an upgrade:

  1. Go to the PerfectDisk site and re-download the full [updated] installer for the client computer.
  2. Install the new version on your client computer. This will update the installer files in the C:\Program Files\Raxco\PerfectDisk10Install\PerfectDisk10_Home_Server folder as well.
  3. Log into the WHS console and uninstall the PerfectDisk add-in. You'll need to restart the WHS console and possibly reboot the WHS after this.
  4. Copy the new add-in from the C:\Program Files\Raxco\PerfectDisk10Install\PerfectDisk10_Home_Server folder into the \\server\software\add-ins folder on your server. You may want to keep a backup copy of the old version of the add-in somewhere before you overwrite it with the new version. Don't put two copies of the add-in in the server's "add-ins" folder, though.
  5. Log into the WHS console and install the new version of the PerfectDisk add-in. It will tell you to restart the WHS console. Do that.
  6. On restarting the WHS console, go to the PerfectDisk add-in and re-enter your product key.

You'll notice that this is pretty close to what a fresh install looks like. You'd be correct. The in-place upgrade for PerfectDisk doesn't work for WHS.

This is all, unfortunately, documented nowhere on the PerfectDisk site. I have submitted a ticket to their support people about this. In the meantime, I figured out a bunch of things you shouldn't do to upgrade the add-in.

Things you should NOT do:

  • Do not try to install the PerfectDisk update on your WHS through the "Check for Updates" feature. This ends you up with a mismatched add-in version and engine version and somehow corrupts the way the add-in is registered with the WHS console.
    • Don't do it from the WHS console.
    • Don't do it from a Terminal Service session to the WHS.
  • Do not update your client computer's PerfectDisk install through the "Check for Updates" feature. That will update your client computer just fine, but it won't update the installers so you won't get the updated WHS add-in.
  • Do not uninstall PerfectDisk on your WHS through Add/Remove Programs. I didn't do this, but it will end up corrupting the way the add-in is registered with the WHS console. Use the WHS console to remove PerfectDisk.

243 Trick-or-Treaters

We had five more trick-or-treaters this year than we had last year and the most popular time to visit was between 7:30p and 8:00p, which is a half hour after last year. From the graph, it appears that kids are coming out later and later - back in 2006 and 2007, 6:30p to 7:00p was the most popular time to visit.

Here's the graph:

2009: 243 Trick-or-Treaters

And the cumulative data from this year and the other years we've tracked:

  Time Blocks
6:00p - 6:30p 6:30p - 7:00p 7:00p - 7:30p 7:30p - 8:00p 8:00p - 8:30p
Years 2006 52 59 35 16 0
2007 5 49 39 25 21
2008 14 71 82 45 25
2009 17 51 72 82 21

Halloween was on a Saturday this year so we prepared for this number of kids by getting two giant bags of candy at Costco. We did think there'd be more, so we have about half a bag of candy left, but at least we didn't run out like we did last year.

We put the Halloween projector out again this year and that was nice but I think I want to do more decorating for next year. I think Halloween's on Sunday next year, so I'm not sure if we'll have quite as big of a turnout, but it's fun to decorate and such.

Around the 6:30p time we had a couple of larger trick-or-treaters show up in something similar to Death Eater masks. They were also wearing some pretty heavy long black coats. They didn't say anything (which isn't out of the ordinary) and just held their bags out. Fine, some high school kids doing their last hurrah. When the next group of kids showed up, though, these larger ones were still there. OK, fine, we'll give you a second piece of candy and send you on your way. But they were there for a third time when kids showed up so I told them, no, they'd already been here twice and it was time for them to move on. As I shut the door, one of them stuck a foot in and got up in my face so I started getting ready to get nasty. "You'll be moving that foot now." Then the doorbell rang and they were there again. I'd had it... and then they said "Trick or Treat!" out loud.

It was my freaking parents.

Man, they got us so good. We had no idea. It was my mom who'd got up in my face because she thought we could see her eyes through the mask. You couldn't - it was total blackout from outside the mask. Wow, did they get us. Not sure we'll be able to get 'em back for that, but we owe them a big one now.

Manually Uninstalling a Windows Home Server Add-In

I just had a bit of a scare with a misbehaving Windows Home Server add-in where the upgrade process went frightfully wrong. As such, I ended up with:

  • The .msi for the add-in in the \\server\Software\Add-Ins folder.
  • The list of add-ins saying the add-in was installed.
  • No add-in actually installed.

Thank goodness there's a great article over on HomeServerLand that tells you how to manually uninstall an add-in. I followed that process and the crisis was averted.