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;

Bernard Vander Beken
  • 4,848
  • 5
  • 54
  • 76
eranj
  • 367
  • 1
  • 3
  • 8
  • What is your end goal with this? Why do you have to do this instead of simply using Settings? – Branko Dimitrijevic Aug 03 '11 at 12:58
  • I want to change this resource without getting into the Visual Studio. – eranj Aug 03 '11 at 13:53
  • same i think i asked http://stackoverflow.com/questions/6757457/re-embedding-sqlite-database-file-into-the-same-executable – Arunkumar Chandrasekaran Aug 03 '11 at 13:56
  • not the same. Here i have a code that actually should do the work but it doesn't. – eranj Aug 03 '11 at 14:51
  • 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. – Justin Aug 03 '11 at 15:03
  • yes, because `ProjectName.Properties.Resources.encFile` is how i get the the file in the EXE.. – eranj Aug 03 '11 at 17:39
  • @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. – Jb Evain Aug 03 '11 at 20:41
  • 2
    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. – Will Aug 05 '11 at 03:42
  • 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. – Dev.Jaap Aug 12 '11 at 13:03
  • 3
    Is the assembly signed? If it is then this will not work, by design. – justin.m.chase Sep 13 '11 at 01:44

1 Answers1

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.

jjxtra
  • 20,415
  • 16
  • 100
  • 140