【发布时间】:2009-07-28 14:58:24
【问题描述】:
当我编译我的一个程序时,会生成一个 DLL。 DLL 包含软件显示的图像。我制作了另一个软件,一个配置器。我希望它能够打开 DLL 并替换横幅,并且只有横幅、图像与用户选择的任何图像,然后重新编译成 dll。我该怎么做?
【问题讨论】:
当我编译我的一个程序时,会生成一个 DLL。 DLL 包含软件显示的图像。我制作了另一个软件,一个配置器。我希望它能够打开 DLL 并替换横幅,并且只有横幅、图像与用户选择的任何图像,然后重新编译成 dll。我该怎么做?
【问题讨论】:
您可能希望使用资源 API - UpdateResource 和朋友。
【讨论】:
有 Microsoft 认可的策略,特别是 PE 映像的资源部分。
但是,我建议在 C 中使用一个大数组,它以某个魔术序列开头,并扩展到已知大小。然后,在替换数组时,搜索魔法序列,然后只替换 DLL 中的字节。
【讨论】:
看看Mono - Cecil。 Cecil 是允许您更改/重写程序集的 IL 代码的工具 (API)。它还应该重写资源。
【讨论】:
您可能应该考虑使用 .NET 中提供的内置 C# 或 VB.NET 编译器即时编译 DLL。实现编译器的确切类是 Microsoft.CSharp.CSharpCodeProvider 和 Microsoft.VisualBasic.VBCodeProvider。两者都在 System.dll 程序集中定义。
或者,您也可以使用随 .NET Framework 安装的 csc.exe、vbc.exe 和 resgen.exe 应用程序来生成 DLL。
这可以通过使用 System.Diagnostics.Process 类生成一个进程来完成。使用它,您可以捕获 Console.In 和 Console.Out 流,以将控制台 I/O 重定向到 StreamReader/StreamWriter,从而与 Configurator 函数紧密集成。
话虽如此,我认为更好的选择是第一个,您使用实际的编译器类,而不是调用可执行文件(在内部也只是调用编译器类)。
如果一切都失败了,CodePlex 上有一个编译器构造器项目可能会有用。它有诸如 PEAssemblyReader 和 PEAssemblyWriter 类(不太确定确切名称)之类的东西,但这些类允许读取和写入 PE 文件。 PE 代表可移植可执行文件,是 Windows 用于可执行文件的格式。但是,在这个选项中,您需要确切地知道如何在内存中修改 PE 结构,然后它们会写出修改后的 PE 结构。
我仍然认为第一个选项是要使用的选项,除非您在运行时没有这些 DLL 的源代码。
【讨论】:
请注意,您对此执行的任何方法都会产生副作用 - 特别是,它会破坏程序集上的任何代码签名。
您可能需要考虑为您的程序集加载一个单独的资源文件。这使得更新变得微不足道。如果您有多个资源,您甚至可以使用某种形式的简单数据库。
【讨论】: