Tuesday, November 15, 2005

C# - Resources – Manifest Resources

Image can be loaded into the application from the file system, for example:
 // Load image from a file path
 Bitmap image = new Bitmap(@"c:\ufo.gif");
But the problem with this method is the application cannot guarantee the file it's looking for will be there. The reasons could be the user removed or moved the file to other location. If the image file the application expecting does not exists, it will cause the application not functioning properly.

The only safe way to make sure that the image, or any file, stays with code is to embed it and load it as a resource, a named piece of data embedded in the assembly itself.

Following command line shows how to embed a file into the assembly:
 csc [source file name.cs] /resource:[resource file name]

 csc ufo.cs /resource:UFOApplication.ufo.gif
The image file will embedded in the assembly’s set of manifest resources. The manifest of an assembly is composed of a set of metadata that’s part of the assembly. Part of that metadata is the name and data associated with each embedded resource.

Following codes shows how to retrieve resources from the assembly manifest:
using System;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;

namespace UFOApplication {
 public class Form1: Form {

  private Assembly assembly;
  private Bitmap image;

  // Constructor
  public Form1() {

   // Get current object type's assembly.
   this.assembly = this.GetType().Assembly;

   // Load the image binary stream from the assembly manifest.
   // Stream stream = this.assembly.GetManifestResourceStream("UFOApplication.ufo.gif");
   Stream stream = this.assembly.GetManifestResourceStream(this.GetType(), "ufo.gif");

   // Construct the bitmap from stream.
   this.image = new Bitmap(stream);  

   this.Paint += new PaintEventHandler(Form1_Paint);
  }

  private void Form1_Paint(object sender, PaintEventArgs e) {
   // Draw the bitmap on the form.
   e.Graphics.DrawImage(this.image, 0, 0); 
  }

  // The main entry point for the application.
  public static void Main() {
   Application.Run(new Form1());
  }
 }
}
Although manifest resources are useful, but there are some limitations. For example, manifest resources are embedded with no type information. So there will be no difference to the Bitmap class for ufo.gif, ufo.jpg, or ufo.xyz, which looking for data itself for the type like JPEG, PNG, GIF and etc.

The proper type of object will be needed to load the relevant type of each resource.

No comments: