Click here to Skip to main content
15,893,487 members
Articles / Programming Languages / Visual Basic

Automate the Manifest Injection Process

Rate me:
Please Sign up or sign in to vote.
4.14/5 (5 votes)
22 Feb 20052 min read 61.4K   356   21  
Automate manifest injection using post-build events.
using System;
using System.IO;
using System.Runtime.InteropServices;

namespace ThemeControl
{
	public class ManifestInjection
	{
		[DllImport("kernel32.dll", SetLastError=true)] 
		static extern int BeginUpdateResource(string pFileName, bool bDeleteExistingResources);

		[DllImport("kernel32.dll", SetLastError=true)] 
		static extern int EndUpdateResource(IntPtr hUpdate, bool fDiscard);

		[DllImport("kernel32.dll", SetLastError=true)] 
		static extern int UpdateResource(IntPtr hUpdate, uint lpType, uint lpName, ushort wLanguage, byte[] lpData, uint cbData);

		public static bool Inject(string AssemblyPath, string ManifestPath, uint ResourceName) 
		{
			byte[] manifestByteArray = null;
			bool result = false;
			FileStream manifestStream = null;
			BinaryReader manifestReader = null;
			IntPtr updatePointer = IntPtr.Zero;
			
			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) 
				{
					// Throws an exception with a specific failure HRESULT value if no pointer is returned
					Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
				}

				// The second argument, 24 (RT_MANIFEST), specifies that the resource is a manifest.  Details are at
				// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/resources/introductiontoresources/resourcereference/resourcetypes.asp
				if (UpdateResource(updatePointer, 24, ResourceName, 0, manifestByteArray, (uint)manifestByteArray.Length) != 1) 
				{
					// Throws an exception with a specific failure HRESULT value if the resulting update does not return 1
					Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
				} 
			}
			catch // (Exception ex) 
			{
				// Manage exception here
				result = true;
			}
			finally 
			{
				if (updatePointer != IntPtr.Zero) 
				{
					// Finalize the update
					EndUpdateResource(updatePointer, result);
				}
				if (manifestReader != null) 
				{
					manifestReader.Close();
				}
				if (manifestStream != null) 
				{
					manifestStream.Close();
				}
			}

			return !result;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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


Written By
Web Developer PageLabs
United States United States
I'm the founder of PageLabs, a web-based performance and SEO optimization site.

Give your site a boost in performance, even take a free speed test!

http://www.pagelabs.com

Comments and Discussions