C# – How to edit resource of an assembly?

Maybe because of a weird requirement, we have to edit a resource of a compiled assembly. We can’t edit an embedded resource directly but only replace it with the new one. In .NET project, there are two ways to add a resource : through Resources.resx in project settings tab or setting a file as embedded resource in Visual Studio. In this post, I’ll show you how to replace an embedded resource of an assembly with Mono.Cecil.

1. Prerequisites

Be sure that the resource you’re replacing is an embedded resource.

Embedded Resource

2. Sample code

In source code, you’ll find a TestAssembly Windows Forms Application. It has an embedded resource type of image called github.png. When the app starts, it shows this image in picture box like this

Show image

private void Form1_Load(object sender, EventArgs e)
{
	Assembly currentAssembly = Assembly.GetExecutingAssembly();
	Stream image = currentAssembly.GetManifestResourceStream("TestAssembly.Resources.github.png");
	if (image != null) pictureBox1.Image = Image.FromStream(image);
}

Now we use Mono.Cecil to replace that image with another image with the following code

private static void Main(string[] args)
{
	string assemblyPath = "TestAssembly.exe";
	string resourceName = "TestAssembly.Resources.github.png";
	string replacingResourcePath = "github2.png";
	string newAssemblyPath = "EditedTestAssembly.exe";

	if (!File.Exists(assemblyPath))
		throw new FileNotFoundException(assemblyPath + " not found");

	if (!File.Exists(replacingResourcePath))
		throw new FileNotFoundException(replacingResourcePath + " not found");
	ReplaceResource(assemblyPath, resourceName, replacingResourcePath, newAssemblyPath);

	if (!File.Exists(newAssemblyPath))
		throw new FileNotFoundException(newAssemblyPath + " not found");
	Process.Start("EditedTestAssembly.exe");
	Console.WriteLine("Done");
}

private static void ReplaceResource(string assemblyPath, string resourceName, string replacingResourcePath, string newAssemblyPath)
{
	var assemblyDef = AssemblyDefinition.ReadAssembly(assemblyPath);
	var resources = assemblyDef.MainModule.Resources;
	var selectedResource = resources.FirstOrDefault(x => x.Name == resourceName);
	if (selectedResource != null)
	{
		var newResource = new EmbeddedResource(resourceName, selectedResource.Attributes, File.ReadAllBytes(replacingResourcePath));
		resources.Remove(selectedResource);
		resources.Add(newResource);
		assemblyDef.Write(newAssemblyPath);
	}
}

When the edited assembly gets started, it will show another image.

Show another image

3. Source code

https://bitbucket.org/hintdesk/dotnet-replace-resource-of-assembly

3 thoughts on “C# – How to edit resource of an assembly?”

  1. Hi,
    I can’t compile because even with Mono.Cecil reference added it still show:
    Severity Code Description Project File Line Suppression State
    Error CS0117 ‘AssemblyDefinition’ does not contain a definition for ‘ReadAssembly’ ReplaceEmbeddedAssemblyResource C:Users\DocumentsVisual Studio 2015ProjectsReplaceEmbeddedAssemblyResource-masterReplaceEmbeddedAssemblyResourceProgram.cs 32 Active
    and
    Severity Code Description Project File Line Suppression State
    Error CS0246 The type or namespace name ‘WriterParameters’ could not be found (are you missing a using directive or an assembly reference?) ReplaceEmbeddedAssemblyResource C:Users\DocumentsVisual Studio 2015ProjectsReplaceEmbeddedAssemblyResource-masterReplaceEmbeddedAssemblyResourceProgram.cs 52 Active

    Is there a way to get an compiled version or a how to fix it ?
    Thank you in advance,
    Raul

  2. @Raul Costa : The post was 8 years old without any update. It won’t work anymore. I’ll check the post again and make an update later.
    Or you can use the code of Christoffer S. posted in his comment above your comment.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.