Mono.Cecil - Не корректно заменяются ресурсы программы
Класс для замены ресурсов:
namespace EditorRes
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Resources;
using Mono.Cecil;
public static class ResourceEx
{
private static string CreateResourceFile(byte[] FileData)
{
string ResPath = Path.Combine(Environment.CurrentDirectory, "res.resources");
using (var Writer = new ResourceWriter(ResPath))
{
Writer.AddResource("Res", FileData);
Writer.Generate();
}
return ResPath;
}
private static string CreateResourceFile(List<byte[]> Files)
{
string ResPath = Path.Combine(Environment.CurrentDirectory, "res.resources");
using (var Writer = new ResourceWriter(ResPath))
{
int index = 0;
foreach (byte[] ByteArray in Files)
{
Writer.AddResource($"Res{index}", ByteArray);
}
Writer.Generate();
}
return ResPath;
}
private static void ReplaceResource(AssemblyDefinition asmDefinition)
{
string ResPath = Path.Combine(Environment.CurrentDirectory, "NewText.txt"); // Путь до нового ресурса
asmDefinition.MainModule.Resources.RemoveAt(0); // Удаляю старый ресурс
Console.WriteLine("Delete old resource");
string ResourceFile = CreateResourceFile(File.ReadAllBytes(ResPath)); // Создаю новый ресурс для добавления
var EmbeddedRes = new EmbeddedResource("ResExtractor.Properties.Resources.resources", ManifestResourceAttributes.Public, File.ReadAllBytes(ResourceFile));
asmDefinition.MainModule.Resources.Add(EmbeddedRes); // Добавляю файл ресурсов
Console.WriteLine("Add new resource");
File.Delete(ResourceFile); // Удаляю файл ресурсов
Console.WriteLine("Delete temp resource");
}
public static void SaveNewBuild()
{
string stubfile = Path.Combine(Environment.CurrentDirectory, "ResExtractor.exe");
string newbuild = Path.Combine(Environment.CurrentDirectory, "New_ResExtractor.exe");
// Читаю сборку
Console.WriteLine("Read Assembly");
using (var read = AssemblyDefinition.ReadAssembly(stubfile))
{
ReplaceResource(read); // Изменяю ресурс
using (AssemblyDefinition ass = read)
{
Console.Write("Write new build ...");
ass.Write(newbuild); // Перезаписываю в новый файл
Console.WriteLine("Successfully");
}
}
}
}
}
namespace EditorRes
{
using System;
internal static class Program
{
[STAThread]
public static void Main(string[] args)
{
Console.Title = "Resource EditorEx [Tested]";
ResourceEx.SaveNewBuild();
Console.Read();
}
}
}
Файл ресурсов оригинального файла:

Вопрос: Что нужно изменить/добавить чтобы корректно файл отображался?!
Тестовый проект: ResourceEditor
Ответы (1 шт):
Автор решения: r3xq1
→ Ссылка
Я смог добавить решение проблемы по замене ресурсов таким способом:
namespace EditorRes
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Resources;
using Mono.Cecil;
public static class ResourceEx
{
private static byte[] CreateByteResourceFileInMemory(string FileData)
{
// Создаю новый ресурс в памяти
using (var ms = new MemoryStream())
{
using (IResourceWriter Writer = new ResourceWriter(ms))
{
Writer.AddResource("Res", FileData);
Writer.Generate();
}
return ms.ToArray();
}
}
private static string CreateStringResourceToFile(byte[] FileData)
{
// Создаю новый ресурс в файле
string ResPath = Path.Combine(Environment.CurrentDirectory, "res.resources");
using (IResourceWriter Writer = new ResourceWriter(ResPath))
{
Writer.AddResource("Res", FileData);
Writer.Generate();
}
return ResPath;
}
private static string CreateResourceFile(List<byte[]> Files)
{
string ResPath = Path.Combine(Environment.CurrentDirectory, "res.resources");
using (var Writer = new ResourceWriter(ResPath))
{
int index = 0;
foreach (byte[] ByteArray in Files)
{
Writer.AddResource($"Res{index}", ByteArray);
}
Writer.Generate();
}
return ResPath;
}
private static void ReplaceResource(AssemblyDefinition asmDefinition)
{
asmDefinition.MainModule.Resources.RemoveAt(0);
var ResourceFile = CreateByteResourceFileInMemory(Properties.Resources.NewText); // File.ReadAllText(ResPath)
var EmbeddedRes = new EmbeddedResource("ResExtractor.Properties.Resources.resources", ManifestResourceAttributes.Public, ResourceFile);
asmDefinition.MainModule.Resources.Add(EmbeddedRes);
}
public static void SaveNewBuild()
{
string stubfile = Path.Combine(Environment.CurrentDirectory, "ResExtractor.exe");
string newbuild = Path.Combine(Environment.CurrentDirectory, "New_ResExtractor.exe");
// Читаю сборку
Console.WriteLine("Read Assembly");
using (var read = AssemblyDefinition.ReadAssembly(stubfile))
{
ReplaceResource(read); // Изменяю ресурс
using (AssemblyDefinition ass = read)
{
Console.Write("Write new build ... ");
ass.Write(newbuild); // Перезаписываю в новый файл
Console.WriteLine("Successfully");
}
}
}
}
}
Всё хорошо заменяется, но есть одна проблема:
Я не могу сохранить содержимое файла из ресурсов на рабочий диск ( уже из изменённого .exe файла ), создаётся пустой файл, как решить пока не знаю, если кто знает, подскажите!
