Select Page

Why embed files ?

Many of my projects use a lot of secondary files. It can be images, icons, xml-files, text, sound, whatever…. These files pose a couple of problems for me:

  • They clutter the program folder.
  • The user may accidentally delete or change them.
  • They expose your graphics/sound files to stealing and copying.
  • They expose program-sensitive information that a user may try to use to hack/change the behaviour of the program.

Luckily there is a fairly easy solution to parts of these problems. Embed the file in the assembly.

Embedding a file

The actual embedding of a file in an assembly in Visual Studio 2008 is very easy indeed. You just add the file to the project, and set the build action to “Embedded Resource”.
The compiler will then automagically embed the file in the assembly, where it will be accessible during runtime, to use as you wish. Of course this will make your assembly grow, and with many files, it may grow a lot, but this is usually no problem. You can embed any type of file, and you can arrange the files any way you want in project folders and the like.

Getting the file from the assembly

Getting the file out of the assembly is almost as easy as getting it in there. It uses functions from the System.Reflection to access the assembly itself, so adding a “using System.Reflection;” to your code is advisable.
There are basically two functions worth noting here:

  • GetManifestResourceNames() – Gets the names of all the embedded resources in the assembly.
  • GetManifestResourceStream(string name) – Returns a stream representing the named resource.

So getting hold of the first resource in an assembly is as easy as:

Assembly A = Assembly.GetExecutingAssembly();
string[] names = A.GetManifestResourceNames();
Stream S = A.GetManifestResourceStream(names[0]);

The above example should get the point across. It is very easy to gain access to an embedded resource as you would access any file.
A more practical example, is using an embedded resource file to set the image of a PictureBox control. It could look like this:

Assembly A = Assembly.GetExecutingAssembly();
Stream S = A.GetManifestResourceStream("MyProject.Images.jakob.gif");
pictureBox.Image = Image.FromStream(s);

In the example here, the actual name of the resource is shown. “MyProject.Images.jakob.gif” is the name of a resource called “jakob.gif” belonging to the project named “MyProject”, and placed in a project folder with the name “Images”. This is a fairly ease naming convention, that makes all resource names unique and easy to figure out. If you ever have doubts about the name of a resource, just call GetManifestResourceNames(), and it will tell you the names.

Saving all the ressources in an assembly to disk

I’m going to finish by showing you a nice trick, that shows of the functions i outlined above. It is a function that iterates through all the resources in an assembly, and saves them to disk. It handles the files as raw byte arrays, so it should work with any file. I have tested it on gif, zip and pdf files, and it works like a charm.

private void SaveAllResources()
{
  Assembly A = Assembly.GetExecutingAssembly();
  string[] names = A.GetManifestResourceNames();

  foreach (string filename in names)
  {
    Stream S = A.GetManifestResourceStream(filename);
    byte[] rawFile = new byte[S.Length];

    //Read the data from the assembly
    S.Read(rawFile, 0, (int)S.Length);

    //Save the data to the hard drive
    using (FileStream fs = new FileStream(filename, FileMode.Create))
    {
      fs.Write(rawFile, 0, (int)S.Length);
    }
  }
}

Have fun embedding 🙂