天天看點

用自删除dll實作應用程式的安裝/解除安裝代碼

為了讓自删除的可執行程式不依賴于 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

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的依賴,必須用靜态連結到運作庫代碼:

注意這裡安裝程式不必等待 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。用它可以在指令行進行解壓縮處理。

繼續閱讀