为了让自删除的可执行程序不依赖于 C 运行时DLL,可执行程序必须静态链接到运行时库代码。为此修改项目编译选项即可:
项目(P)| [项目名称] 属性(P)... | C/C++ | 代码生成 | 运行时库:[单线程(/ML)] 或者 [多线程(/MT)](或者任何不包含此DLL的选项值)
此自删除技术在所有 Windows 版本中都工作得很稳定。在实际运用中,卸载程序首先将自己的拷贝放到 Windows 临时(Temp)目录,以便能删除所有程序文件和相关目录,最后它用自删除的 DLL 把自己删掉。
编写安装程序
确定了安装程序要做些什么事情之后,接着是制作安装程序。现在很多的安装程序都是由用户从Internet上下载,然后在本地运行。那么下载的文件体积 越小越好,为此最有效的方法是对文件进行压缩处理。如何让用户最先看到的画面是我的程序画面而不是其它公司的安装程序画面呢,好在Windows提供了这 样的支持。
首先创建一个交互式的 Setup 程序,它显示软件许可协议,提示用户安装选项,拷贝文件,然后进行其余的设置工作。然后将 Setup 程序的压缩版本作为资源保存在安装程序(installer)中。这个安装程序要做的只是将 Setup 程序二进制资源重建后写回磁盘,解压缩,然后用一个新进程启动它。保存和读写二进制资源并不难——本文前面已经描述了处理细节和代码。
自从 Windows 95 开始的每个 Windows 平台都带一组解压缩文件的 API——LZCopy。下面是安装程序使用这个 API 的示例代码: / install.h
//
#define RC_BINARYTYPE 256
#define ID_COMPRESSED_SETUP 100
//
// install.rc
//
#include "install.h"
ID_COMPRESSED_SETUP RC_BINARYTYPE AppSetup.ex_
//
// install.cpp
//
#include
#include "install.h"
void WriteResourceToFile(HINSTANCE hInstance,
int idResource,
char const *filename)
{
// 参见前述代码
}
void DecompressFile(char const *source, char const *dest)
{
OFSTRUCT ofs;
ofs.cBytes = sizeof(ofs);
int zhfSource = LZOpenFile(const_cast(source), &ofs, OF_READ);
int zhfDest = LZOpenFile(const_cast(dest), &ofs,
OF_CREATE | OF_WRITE);
LZCopy(zhfSource, zhfDest);
LZClose(zhfSource);
LZClose(zhfDest);
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WriteResourceToFile(hInstance, ID_COMPRESSED_SETUP, "AppSetup.ex_");
DecompressFile("AppSetup.ex_", "AppSetup.exe");
DeleteFile("AppSetup.ex_");
// 启动 AppSetup.exe
PROCESS_INFORMATION procInfo;
STARTUPINFO startInfo;
memset(&startInfo, 0, sizeof(startInfo));
CreateProcess(0, "AppSetup.exe", 0, 0, FALSE, NORMAL_PRIORITY_CLASS, 0, 0,
&startInfo, &procInfo);
}
从代码中可以看到压缩的 Setup 程序是如何作为安装程序的资源保存的。按照本文前面讨论的思路。DecompressFile 函数示范了 LZCopy API 的使用方法。安装程序重新创建 AppSetup.exe,然后运行它。为了顺利编译和生成安装程序,需要将 lz32.lib 添加到项目的编译选项中,通常这个文件在 Visual Studio 的安装目录中,如:Visual Studio .NET 2003:
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib
Visual C++ 6.0:
C:\Program Files\Microsoft Visual Studio\VC98\Lib
在 Visual Studio.NET 中的添加方法是:
项目(P)| [项目名称] 属性(P)... | 链接器 | 附加库目录:[添加上述路径之一]
此外,为了摆脱对 C运行时DLL的依赖,必须用静态链接到运行库代码:
项目(P)| [项目名称] 属性(P)... | C/C++ | 代码生成 | 运行时库:[单线程(/ML)] 或者 [多线程(/MT)](或者任何不包含此DLL的选项值)
注意这里安装程序不必等待 Setup 程序完成工作,因为 AppSetup.exe 可以在完成工作后用自删除 DLL 来进行自我删除。
使用 LZCopy API 最具技巧性的部分是它只能解压缩由 compress.exe 压缩的文件。compress.exe是微软公司的一款压缩文件命令行实用程序,它随 SDK 一起提供。也可以在微软的官方FPT站点下载:ftp://ftp.microsoft.com/softlib/mslfiles /CP0982.EXE。运行EXE后会有几个解包文件,其中包括 compress.exe,其它的文件可以忽略或删除。compress.exe 的使用方法如下: compress SourceName DestinationName
所有 Windows 版本都内建了解压缩支持,利用它很容易编写安装程序。此外,所有 Windows 版本也都包含了另一个实用程序:expand.exe。用它可以在命令行进行解压缩处理。
转自:http://www.yuanshengkj.com/wendang1.asp?ID=490&page=3