减少exe文件

时间:2011-09-13 07:59:22

标签: delphi file exe delphi-xe2

使用Delphi(或者通常是任何工具,如果存在的话),是否可以减小exe文件的大小,删除所有未使用但存在的代码?
(例如,存在但从未调用的函数或过程) 我记得使用Pascal,使用unit(没有对象),编译器只包含真正使用的过程和函数,并将从最终的exe中删除单元中未使用的例程。

使用Object-pascal,我记得在Delphi 1中,对象的所有成员都包含在exe中;
有什么变化,直到Delphi-XE2?

5 个答案:

答案 0 :(得分:19)

如果您不使用RTTI,可以将其添加到.dpr文件的顶部(紧跟program之后)以删除额外的RTTI信息:

{$IFOPT D-}{$WEAKLINKRTTI ON}{$ENDIF}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}

如果要将其从所有RTL / VCL单元中剥离出来,那么您还需要将它们包含在项目文件中,以便上述设置生效。我不认为我会建议这样做,因为我不相信减少可执行文件大小值得编译自己的RTL / VCL的复杂性。

您还可以在.dpr文件中的某处添加以下内容:

{$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED}

这将删除.exe中不需要的重定位信息。不要将它添加到DLL或包中!

答案 1 :(得分:8)

reduce the application EXE size - 优秀的文章

(取自上面的链接)

  

通常,使用Delphi创建的EXE文件比EXE文件大   用另一种编程语言创建。原因是VCL。   (当然,VCL有很多优点......)

     

有几种方法可以减少EXE的大小:

     

01)使用EXE-Packer(UPX,ASPack,...) - UPX

     

02)使用KOL。

     

03)在没有VCL的情况下编写应用程序

     

04)使用ACL(API控件库)

     

05)使用StripReloc。

     

06)停用远程调试信息和TD32。

     

07)您可能希望将代码放入dll中。

     

08)请勿在表格上多次放置相同的图像。在运行时加载它们。

     

09)使用压缩图像(JPG而不是BMP)

     

10)在DFM文件中存储较少的属性

答案 2 :(得分:4)

如果您的目标是减小可执行文件的大小,可以使用压缩它的工具并允许执行它,因为它不压缩..(=不是拉链)

例如,您可以检查UPX,它与delphi程序很好地配合使用。

答案 3 :(得分:3)

Delphi有一个智能链接选项,如果我没记错的话默认为ON。它完全符合您的描述。只有已使用的函数和数据链接到您的exe。如果你需要进一步的尺寸压缩,你可以尝试其中一个“exe压缩器”程序。

答案 4 :(得分:1)

只是为了补充其他人写的......

在以下条件下,智能链接器将消除之外的未使用的例程:

  • 该单元有initialization部分 - 遗憾的是RTL / VCL中的许多最大单元(Classes,SysUtils,Windows,Forms ...等等)都有初始化部分,所以如果它们在您的uses条款中,您可以将整个辣酱玉米饼馅链接到您的代码中。 RTL / VCL中的大部分代码都可以重构,以减少或消除这一点,但会破坏向后兼容性。

  • 该例程是类的一部分,并标记为虚拟动态 - 如果您在代码中实例化和对象具有虚拟或动态方法,无论你是否打电话,这些方法都会链接到你的可执行文件中。

可以采取的其他步骤来减少exe文件大小:

  • 利用表单继承 - 如果您有许多类似的表单,请创建一个基本表单供他们继承。这些子表单只会存储与其dfms中的基本表单不同的属性。通过消除dfms中的冗余信息,这可以大大减少可执行文件的大小。

  • 将任何大型图形存储在外部文件中并按需加载它们 - 启动画面,“皮肤”,图标集等可以真正膨胀exe的大小。当Delphi嵌入到exe中时,Delphi并不总是以最有效的格式存储这些文件。

  • 您可以通过在编译后从exe中删除某些未使用的数据来减少10% - 30%的exe大小。有第三方工具可以做到这一点,但你可以通过设置适当的PE头flags来消除一些弊端。在使用之前,请确保您了解每个标志的含义,因为某些标志可能会使您的exe无法使用。

  • 将RTL / VLC的部分复制到您自己的单元中 - 而不是在您的uses子句中包含Classes或SysUtils,创建一个新单元并将您需要的类和函数复制到单元中。然后用它代替。

  • 将代码分解为可加载模块 - 如果有多个exes重用相同的单元,可以使用dll或bpls将它们缩小,而不是将所有内容静态链接到exes中。无论有多少exes需要,dll / bpl只会被加载到内存中。