How do I replace embedded resources in a .NET assembly programmatically?
Asked Answered
S

1

23

I am trying to replace a Resource of an exe (.NET, C#) file using C# code.

I have found this article and made this code (using Mono.Cecil 0.6):

AssemblyDefinition asdDefinition = AssemblyFactory.GetAssembly("C:\\File.exe");
EmbeddedResource erTemp = new EmbeddedResource("encFile", ManifestResourceAttributes.Public);
erTemp.Data = myNewFileBytes;
asdDefinition.MainModule.Resources.RemoveAt(0);
asdDefinition.MainModule.Resources.Add(erTemp);
AssemblyFactory.SaveAssembly(asdDefinition, "C:\\newFile.exe");

The code is actually removing the resource and then adding a new one with the same name. The resource name is encFile and stored as encFile.exe (tried both).

I tested the code and the remove is working (i can tell by the size of the file) and the adding too, but the new file crash just like the file i created with the remove only (for the testing) - it acts like he can't see the replaced resource.

What can i do to fix it? Maybe some changes in the edited EXE file? The EXE file reads its resource this way:

byte[] buffer = ProjectName.Properties.Resources.encFile;

Shrove answered 3/8, 2011 at 12:22 Comment(10)
What is your end goal with this? Why do you have to do this instead of simply using Settings?Nosh
I want to change this resource without getting into the Visual Studio.Shrove
same i think i asked #6757957Parachute
not the same. Here i have a code that actually should do the work but it doesn't.Shrove
Are you sure that the name of the resource is exactly the same? ("encFile") Try examining the resources of the assembly in the debugger to be 100% sure you have the right name.Christie
yes, because ProjectName.Properties.Resources.encFile is how i get the the file in the EXE..Shrove
@eranj, could you be more specific than «the file crashes»? I suggest you apply Kragen's advice and double check that the Resource at index 0 has for name encFile, and not something like ProjectName.encFile. The easiest way is simply to change the data of the resource at index 0 (you have to cast it to EmbeddedResource), instead of creating a new one. Also I strongly suggest you update to Cecil 0.9.x.Rowena
2 things come to mind. The target assembly is strong name signed or cecil is breaking the assembly. Without more information its hard to say what exactly.Racquelracquet
Adapting a .exe file is that really what you want? For security reasons your virusscanner should block that! And also: within the Windows environment your program isn't allowed to write a file within the program files folder. Please reconsider it whether it is an good practice or not.Nitid
Is the assembly signed? If it is then this will not work, by design.Ranna
H
1

Trying to do this seems overly complex. If you need dynamic update of resources, ship your resources as a folder for your application (set items in the folder as content and copy if newer in project properties).

If you need dynamic update at runtime, then it's as simple as either:

1] Allow user to replace items in place or
2] Even better, treat it like word-press themes and allow an override folder for each resource.

If you need to tag each resource with metadata you could use a sqlite database or even easier, allow a matching .meta file for each resource to describe it in more detail.

Finally, if you are allowing digital download of your software, then you might consider code-signing your executable - in which case modifying the executable in any way will not be an option.

Heywood answered 23/8, 2020 at 21:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.