在.NET DLL中是否可能添加/移除/更改嵌入式资源?

23

在.NET DLL编译完成后,是否有可能添加/删除/更改嵌入式资源?如果可以,如何操作?是否有任何需要注意的事项?

编辑:

我希望手动实现这个操作,并最终通过后期构建事件中的脚本自动化执行。

3个回答

22

这非常简单,只需要三行代码。你需要引用mono.cecil.dll(谷歌一下!)以及:

var targetasmdef = AssemblyFactory.GetAssembly("My.dll");
//May seach for the one you need
targetasmdef.MainModule.Resources.RemoveAt(0);
AssemblyFactory.SaveAssembly(targetasmdef, "My2.dll");

6
我已经编写了一个小程序,可以替换嵌入式资源:https://github.com/qerub/ReplaceEmbeddedAssemblyResource - qerub
AssemblyFactory.GetAssembly was removed. Use AssemblyDefinition.ReadAssembly - PeterB

21
在托管代码中无法实现这一点。一旦资源被嵌入,它就像编译后的 MSIL 代码一样成为程序集的一部分。
然而,可以手动完成此操作,就像 Lucero 建议的那样,通过使用 ildasm 将 DLL 反汇编为文本文件,使用文本编辑器删除资源,最后使用 ilasm 重新组装 DLL。
以下是使用单个嵌入式文本文件的 DLL 的示例:
1)将 DLL 反编译为 MSIL:
ildasm MyLibrary.dll /out=MyLibrary.il

2) 打开生成的MyLibrary.il文件并移除.mresource部分:

.mresource public MyLibrary.MyResource.txt
{
  // Offset: 0x00000000 Length: 0x0000000F
  // WARNING: managed resource file MyLibrary.MyResource.txt created
}

3)根据修改后的MyLibrary.il文件重新组装DLL:

ilasm MyLibrary.il /dll

我在使用第三方库的嵌入式许可证方面遇到了问题。当我们将许可证嵌入到我们的库中时,它依赖于特定的版本。我希望能够创建两个版本的程序集,一个没有许可证,一个有许可证。 - Mas
@Enrico - 你有什么想法,为什么Lucero的解决方案不可行吗? - Kieren Johnstone
@Kieren 我认为 @Mas 的意思是以编程的方式。@Lucero 提出的手动方式可行。我在他的答案中添加了一个链接,并提供了一个示例。 - Enrico Campidoglio
2
@Enrico,没有什么可以阻止你以编程方式做与“ILDASM”和“ILASM”相同的事情...另外,你关于手动过程的说明不完整。对于反汇编,你应该添加“/utf8 /typelist /all”,而对于重新组装,“/resource=MyLibrary.res”。 - Lucero
@Lucero 这个该怎么以编程的方式实现呢?我用一个包含嵌入式文本文件的示例控制台应用程序尝试了一下这些指示,它起作用了。这些说明只是一个示例,其他情况需要不同的参数集。 - Enrico Campidoglio
显示剩余3条评论

6
是的,这是可能的,可以通过使用ILDASMILASM进行往返操作,在其中替换嵌入的文件。
需要注意的事项:
  • 如果程序集被强名称,你需要强名称密钥文件,否则最终得到的程序集名称将不同。
  • 如果程序集使用证书签名,你需要包括私钥的证书以重新签名(如果需要)。
  • 混淆的程序集可能由于名称问题而无法进行往返操作。

很好,这听起来是一个有趣的解决方案。谢谢! - Mas
1
另一个注意事项:混合模式程序集在通过ILDASM时无法完全反汇编,因此无法通过ILASM重新编译。 - coderforlife

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接