Visual Studio .NET 2002Visual C++ 7.0Windows 2000Visual C++ 6.0Windows XPMFC中级开发Visual StudioWindowsC++
创建自解压可执行文件





4.00/5 (6投票s)
2002 年 9 月 16 日
2分钟阅读

99569

2191
如何以最小的开销创建自解压可执行文件。
引言
在本文中,我将简要介绍如何创建自解压可执行文件。
了解可执行文件
当操作系统执行一个可执行文件时,它知道如何执行它,这归功于PE头,它是一个大表,在文件开头保存了关于可执行文件的所有信息以及它包含的内容(不同的节)。
因为我们不允许修改可执行文件本身(我们不想造成损害),所以我们的起点将是文件的末尾。
为了使附加方法和分离方法使用相同的语言,我们需要设置一种格式
固定大小 | |
可执行文件 | |
文件名长度 | X |
文件名 | |
文件内容 | |
文件名长度指针 | X |
签名 | X |
使用这种格式,我们不受文件名或文件内容的特定大小的限制。
为了明确起见,当我们从合并的文件(可执行文件 + 附加文件)中分离文件时,文件结尾是新的文件结尾,这就是为什么文件结尾是固定大小并且会给我们关于附加文件的信息非常重要。 在上表中,固定部分是“文件名长度指针”和“签名”部分。
实现
为了实现这样的任务,我们需要两个基本方法
attachFile
- 将文件附加到自解压可执行文件。detachFile
- 获取附加的文件并将其写入磁盘。
为了方便起见,可以实现其他方法
checkSignature
- 检查文件是否附加了文件。
使用上述方法,很容易创建一个自解压可执行文件。
示例(使用 SelfExtract 类)
为了创建一个用于附加和分离的可执行文件,我们需要 checkSignature
方法的帮助。
使用此方法,我们可以确定操作模式。 如果我们附加了文件,我们处于分离模式;如果我们没有附加文件,我们处于附加模式。
为了多次使用该工具,每次我们附加文件时,我们不会将文件附加到调用可执行文件,而是使用 CopyFile API 复制它。
最容易理解的方法是查看以下示例(可以在页面顶部下载)
int _tmain(int argc, _TCHAR* argv[]) { SelfExtract self; if (self.checkSignature()) { puts("Detaching internal file, please wait..."); // detecting output diretory. // if no parameter then current directory. char *outDir = 0; if (argc > 1) { outDir = argv[1]; } char detached[MAX_PATH]; // detaching internal file. self.detachFile(outDir, detached, MAX_PATH); printf("file %s detached successfully.\n", detached); return 0; } // if no file is attached. else { // missing parameter(s) - showing command line parameters. if (argc < 3) { puts("SelfExtract class example utility, by Nir Dremer"); printf("Usage: %s resultFile attacheFile\n", argv[0]); puts("resultFile is executable you want to create that will be self extracted."); puts("attacheFile is the file you want to attach to resultFile."); return 0; } printf("Creating %s, please wait..", argv[1]); // copying this file as a header for the self extracted executable. CopyFile(argv[0], argv[1], true); self.setFilename(argv[1]); // attaching the attache file. self.attachFile(argv[2]); printf("Process completed, execute %s to detach.", argv[1]); } return 0; }
高级问题
SelfExtract
类仅支持附加/分离一个文件。 我认为这已经足够了,因为如果你想要多个文件,最好先压缩这些文件(有很多开源压缩库),然后附加压缩后的文件。