【问题标题】:How I Compile Resources into my Application and Access them?我如何将资源编译到我的应用程序中并访问它们?
【发布时间】:2011-05-18 18:45:45
【问题描述】:

如何制作包含 DLL 和图像资源文件的单个 executable 包?

那么如何在运行时从我的可执行文件中提取它们?

【问题讨论】:

  • 可能的答案范围从“将它们添加为资源”到“更好地使用安装程序生成器”到“不,你不能这样做”,具体取决于您想要的为什么将文件放入可执行文件中,并在文件放入可执行文件后做什么。那么,什么以及为什么?
  • 因为我打算将该文件用作单个可下载文件,接下来会发生什么并不重要。
  • @Kermia,除非你这样做是为了练习,否则你对大 EXE 文件所做的一切都会让世界变得不同。提示:如果您的 EXE 依赖于 DLL,则将它们作为资源存储在同一个 EXE 中将不起作用,因为除非您首先提取它们,否则您无法链接到它们。如果您为了下载大小而这样做,请考虑使用安装程序。
  • @Kermia,那么就可以了。如果我记得有一个名为 ExeMod 的 Delphi 示例(不是我写的,你必须谷歌它),这显示了如何创建自己的安装程序,搜索 ExeMod.pas - 这可能是一种粗略的方式,但如果我记得,它会起作用。否则你正在做的方法我看不出为什么不这样做。
  • @Craig,@Kermia,如果您想编写自己的安装程序,一个很好的起点是查看Inno Setup 的工作原理。它是用 Delphi 编写的开源代码!不妨修改它来做你需要的,而不是从头开始。甚至可能会发现您不需要自己编写,因为它非常好

标签: delphi resources package


【解决方案1】:

使用 IDE(Delphi 2007 或更高版本)的选项 1:

您可以单击项目菜单,然后选择资源...,您可以将任何文件加载到其中。出于您的目的,这将是 RC_DATA。

不带 IDE 的选项 2

如果您没有上述选项,则需要使用 BRCC32(Borland 资源编译器)从 RC 文件创建一个 .RES 文件,然后将其链接到您的应用程序。要在不使用 IDE 的情况下链接资源文件,请尝试以下操作:

假设我们要添加几个 DLL 文件,DLL 文件的名称是 MyLib1.dll 和 MyLib2.dll,以添加这个打开的记事本,然后键入以下内容:

MYLIB1 RCDATA "..\MyLib1.dll"

MYLIB2 RCDATA "..\MyLib2.dll"

确保 ..\xxx.dll 路径正确,因此显然您需要对其进行编辑。

现在您需要将其保存为 .rc 文件,因此 File>Save As..(确保下拉过滤器为 All Files .)并将其命名为 MyResources.rc。现在你需要使用 Resource Compiler 来生成 Res 文件,使用这个控制台命令:

BRCC32 MyResources.RC

您可以使用命令提示符,开始菜单 > 运行 > cmd.exe 来编写该命令,或者您可以在 Delphi 设置的 bin 文件夹中找到 BRCC32.exe,然后将 MyResource.RC 文件拖到上面。

这将创建一个名为 MyResources.RES 的 Res 文件,您可以将其包含在应用程序的 Main Delphi 表单中,如下所示:

{$R *.dfm}
{$R MyResources.res} 

您可以使用以下方法提取资源:

procedure ExtractResource(ResName: String; Filename: String);
var
  ResStream: TResourceStream;
begin
  ResStream:= TResourceStream.Create(HInstance, ResName, RT_RCDATA);
  try
    ResStream.Position:= 0;
    ResStream.SaveToFile(Filename);
  finally
    ResStream.Free;
  end;
end;

【讨论】:

  • 谢谢,我怎样才能在不使用IDE(编写代码)的情况下添加新资源?
  • 如果通过代码,你的意思是我建议的第二个选项,那么我将编辑我的第一个答案以显示这种方式。
  • 对不起,我看不懂这部分:using this console command: BRCC32 MyResources.RC我应该在哪里写这个命令?
  • 你可以将 MyResources.RC 本身添加到项目中,无需手动编译到 .res
  • 在Delphi 2007中,Project菜单下没有Resource项。
【解决方案2】:

我发现方便的是使用 .zip 容器。

那么你将有两个实现:

  1. 将一些 .zip 内容附加到现有 .exe,.exe 代码将根据请求检索 .zip 内容;

  2. 将 .zip 内容作为资源嵌入,然后根据请求提取每个内容。

解决方案 1 将在编译后添加 .zip 内容。而 2 将在编译时添加 .zip 内容。对于安装程序,我认为解决方案 1 对我来说很有意义。对于检索链接到特定 exe 版本的一些所需文件(库,甚至位图或文本)的方法,可以设想解决方案 2。

使用 .zip 作为格式可以轻松解析内容并允许压缩。使用 TotalCommander 之类的工具,您甚至可以在 .exe 上使用 Ctrl+PgDown 读取 .zip 文件内容。很方便。

您会发现 in this link 如何实现解决方案 1,以及 in this link(同一页面,但另一篇文章)如何使用 TZipRead.Create() 构造函数直接访问捆绑为资源的 .zip。您将在我们的存储库中找到它如何与工作应用程序一起使用:例如我们如何在 SynProject 可执行文件中嵌入图标、文本内容和 graphviz + 拼写检查库。

关于性能,两种解决方案没有区别,至少在我们的代码中是这样。两者都使用内存映射文件来访问内容,因此它或多或少是相同的:非常快。

【讨论】:

  • +1 表示“将数据附加到 exe”。更适合安装程序,显然这就是 OP 正在做的事情。
  • 最后,我下载了它,但现在,当我要使用它时,我得到了这些错误:[DCC Error] SynZip.pas(1179): E1026 File not found: 'deflate.obj'[DCC Error] SynZip.pas(1179): E1026 File not found: 'deflate.obj'
  • 查看源代码存储库:您将能够从synopse.info/fossil/dir?ci=tip 下载所有需要的 .obj 文件
猜你喜欢
  • 2013-09-23
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 2018-12-14
  • 2012-07-14
  • 1970-01-01
  • 2011-10-31
  • 2020-05-03
相关资源
最近更新 更多