Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Manifest File Injection

0.00/5 (No votes)
9 May 2004 1  
Embed a manifest into an executable as a resource for XP Theme support.

Sample Image - ManifestInjection.jpg

Introduction

It's easy enough to include a manifest file with your application to provide XP theme support, but it's one more file to worry about when distributing an application. A more graceful solution is to include the manifest in the executable as a resource. It's not possible to include the manifest as a resource using the IDE because of the way the IDE handles embedded resources. This project aims at “injecting” a manifest directly into the exe after the exe is compiled, to provide full XP theme support.

Using the code

There are only a few key steps to get your manifest into the executable. The first is to read in the manifest as an array of bytes. That array is passed to the UpdateResource API provided by the kernel32 DLL. The only other code to note here is that, before UpdateResource can be called, you must call BeginUpdateResource. Last, in the finally block, EndUpdateResource is called regardless of the update success. The sample project implements the code as a static method, requiring the assembly path, the manifest path, and the name of the manifest to be injected (typically an int).

try
{
    // Read in the manifest as an array of byest to be injected to the 
    manifestStream = new FileStream(ManifestPath, FileMode.Open,
    FileAccess.Read);
    manifestReader = new BinaryReader(manifestStream);
    manifestByteArray = manifestReader.ReadBytes( (int)manifestStream.Length );
    // Begin the injection process
    updatePointer = (IntPtr)BeginUpdateResource(AssemblyPath, false);
    
    if (updatePointer == IntPtr.Zero)
    {
        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
    }
    if (UpdateResource(updatePointer, 24, ResourceName, 0, manifestByteArray, 
                 (uint)manifestByteArray.Length) != 1)
    {
        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
    }
}
catch    
{
    result = true;
}
finally
{
    if (updatePointer != IntPtr.Zero)
    {
        EndUpdateResource(updatePointer, result);
    }
    if (manifestReader != null)
    {
        manifestReader.Close();
    }
    if (manifestStream != null)
    {
        manifestStream.Close();
    }
}

The sample project implements the code as a static method requiring the assembly path, the manifest path, and the name of the manifest (typically an integer value) to be injected as arguments. Run the TestForms.exe to make sure it displays standard Windows controls. Use the sample app to browse for a .NET WinForms app (e.g., the TestForm.exe included with the project). Browse for a manifest file (also included in the sample project's directory). Inject the manifest into TestForm.exe and open TestForm.exe again.

For details on the API, see the MSDN article at: http://msdn.microsoft.com/en-us/library/ms648049(VS.85).aspx.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here