Updating images in exe resource section (in C # / C)

I have several images embedded in my executable in the resource section. I followed these steps to create my executable file:

  • The generated .resx file for all images (.jpg) in the directory using some utility. Images are called image1.jpg, image2.jpg, etc.
  • created a .resources file from a .resx file using: resgen myResource.resx
  • Embeds the generated .resource file using the / res flag as: csc file.cs /res:myResource.resources

4 I refer to these images as follows:

 ResourceManager resources = new ResourceManager("myResource", Assembly.GetExecutingAssembly()); Image foo = (System.Drawing.Image)(resources.GetObject("image1")); 

Everything is working fine, as expected. Now I want to change the embedded images to some new images. This is what I am doing now:

 class foo { [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources); [DllImport("kernel32.dll", SetLastError = true)] static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, string wLanguage, Byte[] lpData, uint cbData); [DllImport("kernel32.dll", SetLastError = true)] static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard); public static void Main(string[] args) { IntPtr handle = BeginUpdateResource(args[0], false); if (handle.ToInt32() == 0) throw new Exception("File Not Found: " + fileName + " last err: " + Marshal.GetLastWin32Error()); byte[] imgData = File.ReadAllBytes("SetupImage1.jpg"); int fileSize = imgData.Length; Console.WriteLine("Updaing resources"); if (UpdateResource(handle, "Image", "image1", "image1", imgData, (uint)fileSize)) { EndUpdateResource(handle, false); Console.WriteLine("Update successfully"); } else { Console.WriteLine("Failed to update resource. err: {0}", Marshal.GetLastWin32Error()); } } } 

The above code adds a new resource for the specified image (inside the IMAGE title with some random number, as shown in the Resource hacker ), but I want to change the existing resource data for image1 .

I am sure that I am UpdateResource with some invalid arguments.

Can anyone help point this out?

I am using .NET version 2

Thanks,

Vikram

+8
c # resources
source share
3 answers

I think you are confusing .NET resources and Win32 resources. The resources you add embedding with the /res argument to csc.exe are .NET resources that you can successfully read using the ResourceManager snippet code.

Win32 resources is another beast that is not very "compatible" with the managed .NET world in general, although you can really add them to .NET exe using the /win32Res argument - note the subtle difference :-)

Now, if you want to change the built-in .NET resources, I donโ€™t think there are classes for this in the structure itself, however you can use Mono.Cecil . Here is an example that demonstrates this here: C # - How to edit an assembly resource?

And if you want to change the built-in Win32 resources, you will need some correction of the code, here is a slightly modified version of it, the most important difference is the declaration of UpdateResource :

  [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources); [DllImport("kernel32.dll", SetLastError = true)] static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, short wLanguage, byte[] lpData, int cbData); [DllImport("kernel32.dll")] static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard); public static void Main(string[] args) { IntPtr handle = BeginUpdateResource(args[0], false); if (handle == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error()); // this will automatically throw an error with the appropriate human readable message try { byte[] imgData = File.ReadAllBytes("SetupImage1.jpg"); if (!UpdateResource(handle, "Image", "image1", (short)CultureInfo.CurrentUICulture.LCID, imgData, imgData.Length)) throw new Win32Exception(Marshal.GetLastWin32Error()); } finally { EndUpdateResource(handle, false); } } 
+8
source share

It's impossible. You cannot change the compiled file that you are using.

+1
source share

I believe that you can add new images at runtime, but you cannot update a resource that is essentially just stored in memory.

If you add a resource at runtime, it exists, but I donโ€™t think it is compiled, and therefore I donโ€™t think it is available to you.

Is there a reason you are not using content?

0
source share

All Articles