最近整理电脑里一堆用C#或者C++写的小工具,打包成EXE文件后,一个个都跟吹气球似的,动不动就几十上百兆,看着就心烦。我想着这些也就几万行代码的小东西,怎么能弄这么大?用户下载安装也麻烦,我都觉得不好意思发给别人。
一开始我试过各种压缩软件,比如什么WinRAR、7-Zip这些,压缩完的体积确实小了一点,但装好后用户还是得先解压,再运行,多了一个步骤,用户体验立马就差了。而且有些杀毒软件还会把这些自解压的包当成病毒,拦着不让运行,太麻烦了。
我寻思着,有没有办法能直接把EXE文件本身给瘦身了,不用用户多操作,打开就是那个小巧的版本?我记得以前玩嵌入式或者做一些单片机程序编译的时候,大家都很注意代码的体积,那时候接触过一些专门针对二进制文件的处理工具。
我决定从EXE文件的结构入手。一个EXE文件,除了我们写的代码,还带着一大堆调试信息、资源文件、.NET的运行时库(如果是托管代码),还有一些没用的区段。这些东西堆在一起,体积自然就上去了。

我找了半天,终于找到了一个工具,能对PE文件(Windows下的可执行文件格式)下手。这个工具可以干两件事:一是把调试信息剥离掉,二是压缩代码段和数据段。
第一步,我先把一个我打包好的,足足有80M的C#小工具放进去试试水。
第二步,就是真正的压缩环节了。这个工具里有个选项,叫“Compress Sections”。我选择了最激进的压缩算法,就是希望能把代码的冗余部分尽量压缩进去。
我点击了执行压缩。工具开始转圈圈,它是在对EXE文件的特定段(比如.text段)进行压缩,然后修改PE文件头里的入口点信息,确保程序运行时能先跳到一个小小的解压代码,把内容在内存里解压出来再跑。

等它跑完,我看了看新生成的文件。我的天,原本80M的文件,直接压缩到了25M!足足瘦了三分之二。我赶紧双击运行试试看,运行速度完全没感觉变慢,几乎是秒开,比之前用压缩软件打包的还要流畅。
这个过程就是对二进制文件动手术。对于那些用VC++或者Delphi编译的原生程序效果最因为它们本身结构更纯粹。如果是.NET程序,虽然也能压缩,但因为运行需要附带CLR,所以瘦身效果不如原生程序那么夸张,不过也挺明显。
我把这个工具的方法记录了下来,特别是对那些做桌面应用,又不想用户下载一堆东西的开发者来说,绝对是把EXE变“苗条”的杀手锏。以后打包软件,再也不用担心文件体积太大,占硬盘空间了,用户体验也好了不少。