如何以编程方式替换 .NET 程序集中的嵌入式资源?

Posted

技术标签:

【中文标题】如何以编程方式替换 .NET 程序集中的嵌入式资源?【英文标题】:How do I replace embedded resources in a .NET assembly programmatically? 【发布时间】:2011-10-19 01:48:56 【问题描述】:

我正在尝试使用 C# 代码替换 exe(.NET、C#)文件的资源。

我找到了this article 并制作了这段代码(使用 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");

代码实际上是删除资源,然后添加一个具有相同名称的新资源。 资源名称为encFile 并存储为encFile.exe(都试过了)。

我测试了代码并且删除工作正常(我可以通过文件的大小来判断)和添加,但是新文件崩溃就像我只使用删除创建的文件(用于测试)一样 - 它表现得好像他看不到被替换的资源。

我能做些什么来解决它?也许在编辑的 EXE 文件中有一些变化? EXE 文件以这种方式读取其资源:

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

【问题讨论】:

您的最终目标是什么?为什么你必须这样做而不是简单地使用设置? 我想在不进入 Visual Studio 的情况下更改此资源。 我想我问过***.com/questions/6757457/… 我想到了两件事。目标程序集是强名称签名或 cecil 正在破坏程序集。没有更多信息,很难说到底是什么。 程序集签名了吗?如果是这样,那么根据设计,这将不起作用。 【参考方案1】:

尝试这样做似乎过于复杂。如果您需要动态更新资源,请将您的资源作为应用程序的文件夹发送(将文件夹中的项目设置为内容,如果项目属性较新则复制)。

如果您需要在运行时动态更新,那么很简单:

1] 允许用户原地替换项目或 2] 更好的是,将其视为 word-press 主题并允许每个资源的覆盖文件夹。

如果您需要使用元数据标记每个资源,您可以使用 sqlite 数据库,甚至更简单,允许每个资源的匹配 .meta 文件更详细地描述它。

最后,如果您允许以数字方式下载您的软件,那么您可能会考虑对您的可执行文件进行代码签名 - 在这种情况下,以任何方式修改可执行文件都不是一种选择。

【讨论】:

以上是关于如何以编程方式替换 .NET 程序集中的嵌入式资源?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式加载嵌入式资源文件

查找其他程序集中的所有嵌入资源

以编程方式替换选择器图像

如何以编程方式撤销、推断、反编译、逆向工程用于在数据集中构造变量的算法

如何发现嵌入式资源的“路径”?

abp 嵌入资源(视图cssjs)的访问