减小Windows可执行文件大小

7
我有一个C++/MFC应用程序在Windows上,动态链接时只有60kb,静态链接时超过3Mb。它通过电子邮件分发给客户,因此需要尽可能小。
它静态链接了MFC和MSCVRT库-因为这是一些问题的修复,我不想再接到更多关于丢失库的支持电话-特别是非常有帮助的“应用程序配置不正确”的电话!
有没有办法剥离Windows exe中所有额外的MFC内容,即dll但我不使用的内容?或者告诉它动态链接MSVCRT(必须存在),但静态链接MFC dll(可能不存在)?
编辑-谢谢,把它减少到1.6Mb就可以了!
4个回答

11
针对使用CRT库的程序,您可以使用Per Vognsen在此视频中介绍的方法来实现3.5KB的可执行文件大小。由于Windows\System32\msvcrt.dll自Windows 95以来已经内置在每个Windows系统中,因此通过链接该库,您无需将Visual C++ Redistributable打包到您的应用程序中。
基本步骤如下:
  1. System32\msvcrt.dll运行Visual Studio的dumpbin并将结果输出到一个文件
  2. 运行一个简单的过滤器(awk '{print $4}')来创建一个msvcrt.def文件
  3. msvcrt.def运行VS的lib以生成msvcrt.lib
  4. 在项目中禁用默认的库文件(在link命令行上使用/NODEFAULTLIB)
  5. 禁用一些Visual C++检查项(/GS-和移除任何/RTC<x>标志)
连接时链接kernel32.libmsvcrt.lib即可,这样您的小型可执行文件除了操作系统外就没有任何其他依赖了。
(注意:为了优化可执行文件大小(/O1),请将memset指定为内置函数,如这里所述。)

1
对我来说并不明显,dumpbin命令需要传递"/exports"开关。例如:dumpbin /exports System32\msvcrt.dll >msvcrt.dll.dump - Andrew Bainbridge

10

您不能混合使用CRT/MFC dlls。根据记忆...

正如其他人所建议的,您可以使用#define WIN32_LEAN_AND_MEAN和VC_EXTRALEAN。然而,这些可能不会有太大帮助。它们往往是用于最小化编译时间 - 而不是最终exe文件大小。

除非重新构建MFC(这是一个选项 - 您可以重新构建为/Os,或者如果您感到非常自负,可以使用/GL - 但这可能会导致更多的下游问题 - 希望已经构建了/Gy)。

好的。尝试简单的事情。使用/GL /Os /GF /Gy /GA构建您的应用程序。在链接器中,您基本上需要使用/OPT:REF和/OPT:ICF和/LTCG。

我必须说 - 从30k到几兆字节的发布版本构建有点过于夸张了。您还可以通过将/map:传递给链接器来查看占用所有空间的内容 - 但这非常繁琐。

这似乎几乎像是MFC没有使用/Gy构建 - 但这令人惊讶。


9
我不确定如何去除可执行文件,但另一个想法是压缩它,例如使用upx,这将解压并在原地运行它... 这样能减小足够的大小吗?

2
UPX非常出色,我的一个应用在使用UPX之前为6MB,在使用UPX之后为2MB! - KPexEA
这似乎是一个很棒的工具,但是对于.NET文件(C++ CLR)无法正常工作。当我尝试在我的exe上运行时,会抛出“CantPackException:.NET文件尚不支持”的异常。 - kiner_shah
1
@kiner_shah - 是的,此页面列出的解决方案均适用于MFC应用程序,而不是.NET应用程序。 - Stobor
我将其用于另一个exe。效果非常好,从23 MB减少到了7 MB。 :-) - kiner_shah

1
您可以尝试使用Dependency Walker来检查您的静态 EXE 文件依赖哪些 DLL,如果它依赖于一个您确定存在于客户机器上的库,则可以在不使用它的情况下编译并减小文件大小。

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