October 2006 Archives

The Silicon Valley Code Camp 2006 was executed very well. I arrived early at 8am, since I had signed up for the Vista Install Fair slot at 9am. I had hoped to get Vista installed on my laptop (Dell Inspiron E1505) in time to attend the Windows Communication Foundation seminar at 9:45am. No such luck, as I was in the Microsoft room from 8:45am until 1pm. Microsoft gave everyone who attended the event a disk with the VUA (Vista Upgrade Advisor) and a sheet of instructions. Included on the disk were diagnostic tools that recorded data about our computers, so the Microsoft engineers could run diagnostics on the later. My computer had two problems: one, the VUA failed to execute successfully, and two, the Vista Upgrade failed with a blue screen dump. And it failed so miserably that we couldn't even perform the rollback to Windows XP.

The clean install of Vista worked perfectly (and I am using the computer right now). I installed Visual Studio 2005 and Office 2007--they both performed well in this environment. It just confirmed for me what I already firmly believed, namely that it's better to freshly install Vista than doing the upgrade. I saw a number of people having problems due to the Upgrade process. Nevertheless, I am happy to help out Microsoft in exchange for a free product key!

Despite missing out on 2 seminars, I enjoyed hanging out in the room with the Microsoft engineers. They answered a number of questions and were very patient looking at everyone's computer. They demoed a number of new Vista features, including ReadyBoost, where you get a performance boost from a USB 2.0 flash drive. I had just bought one at CompUSA, but I was disappointed when Vista reported that it didn't perform well enough for ReadyBoost. I wish I had read this excellent article over at ExtremeTech where they test 9 USB 2.0 Flash drives and see if they can be used by ReadyBoost.

In an earlier article (Accessing Embedded Resources using GetManifestResourceStream) I showed how to retrieve resources from an Assembly. In that particular case, the executing Assembly contained the embedded resource that we wanted to retrieve. What happens when the embedded resource is not in the executing Assembly? When it's located in a different C# Assembly, in a library built for controls or standalone classes? You can still do it, but you can't use GetExecutingAssembly.

In my case, I am building a library containing some Image controls, called CrystalUtils. This particular library contains a C# class for displaying Thumbnail images. When the control is used within the Visual Studio designer, I want to display a default thumbnail image. To access the default image, I have a class called CrystalTools which contains a static method called GetDefaultImage:

public class CrystalTools
{
  static private Bitmap _defaultImage = null;
  static private Image _defaultThumbnailImage = null;
  static public string DefaultImageName = 
        "CrystalUtils.resources.DefaultImage.bmp";

  static public Image GetManifestImage(Assembly theAssembly,
      string imageResourceName)
  {
    if (theAssembly != null)
    {
      Stream _imageStream;
      _imageStream = theAssembly.GetManifestResourceStream(
            imageResourceName);
      return new Bitmap(_imageStream);
    }

    return null;
  }

  static public Image GetDefaultImage(Assembly theAssembly)
  {
    if (_defaultImage == null)
      _defaultImage = (Bitmap)GetManifestImage(theAssembly, 
            DefaultImageName);

    return _defaultImage;
  }

GetDefaultImage takes an Assembly object as the first parameter. The Assembly object you pass cannot be the executable, you need to get the Assembly object that the caller knows contains the desired resource. In this case, a non-static object called CrystalFlipper is calling default image:

Image theImage = CrystalTools.GetDefaultImage(
    Assembly.GetAssembly(typeof(CrystalFlipper)));

Assembly.GetAssembly takes a Type parameter. Each C# class has its own unique type identifier. The typeof operator returns the correct type for the class CrystalFlipper. When I first tried this, I called it this way:

Image theImage = CrystalTools.GetDefaultImage(
    Assembly.GetAssembly(GetType()));

GetType() did work in my test application just fine. When I used it in a real application, I derived a class from CrystalFlipper and overrode some virtual methods. At that point, GetDefaultImage threw an exception. GetType() returned the type of the child class, not CrystalFlipper. While I could see that behavior working in different situations, in this case the typeof() operator gave me access to the same Assembly that my thumbnail classes originated from.