前段時間朋友接了一個項目,具體是開發一個安裝在區域網路内的軟體,這個軟體會定時連接配接區域網路内的伺服器來更新本地用戶端的一些資訊,因為在區域網路記憶體在着多種不同的Windows版本,從WindowsXP、Windows2003及Windows2008到Windows7等,這個軟體采用VS2008/.Net Framework2.0開發,因為有些系統預設沒有安裝.Net Framework2.0,是以在運作時需要確定客戶機上已經安裝上.Net Framework2.0,于是想到将軟體打包。
制作軟體安裝包有幾種工具和方案:一是利用Visual Studio自帶的安裝包制作工具;二是利用InstallShield這類收費的、專業的安裝包制作工具;三是利用Inno Setup這類免費的、專業的安裝包制作工具。
對Visual Studio自帶的安裝包制作工具研究得不深,早期曾經嘗試過将軟體打包成一個安裝檔案内,不過最終失敗了,後來幹脆就不再研究了;InstallShield這類收費的安裝包制作軟體功能确實強大,不過上手确實也不容易,再加上是收費的(盡管可以找到破解版,但是總覺得不爽),于是轉而尋求利用Inno Setup來解決。
Inno Setup 是一個免費的 Windows 安裝程式制作軟體,它支援現在所有正在使用的 Windows 版本: 7, 2008 R2, Vista, XP, 2008, 2003, 2000, Me, 98, 95, 和 NT 4.0 (不需要服務包)。 并且Inno Setup最早出現在1997年,是一個免費開源的軟體,即使作為商業使用也是如此。Inno Setup的官方網站網址是http://www.jrsoftware.org,當然也可以下載下傳它的中文版本,比如[楓林夜思雨]漢化的Inno Setup就還不錯,我給朋友打包時用的是英文版Inno Setup檔案,隻不過安裝檔案中用到的.isl檔案被我翻譯成中文了。
我們想到的辦法就是将軟體制作成安裝包,運作安裝包的時候會檢查客戶機上是否安裝了.Net Framework2.0,如果沒有則從區域網路内伺服器上下載下傳.Net Framework2.0安裝檔案安裝,然後繼續安裝和配置開發的軟體。
從網上搜到這個一個解決方案,代碼如下:
[code]
function InitializeSetup: Boolean;
var Path:string ;
ResultCode: Integer;
begin
if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\.NETFramework\policy\v2.0') then
begin
Result := true;
end
else
if MsgBox('系統檢測到您沒有安裝.Net Framework2.0,是否立刻下載下傳并安裝?', mbConfirmation, MB_YESNO) = idYes then
begin
Path := ExpandConstant('{pf}\Internet Explorer\iexplore.exe');
Exec(Path, 'http://www.xxx.com/down/dotnetfx2.exe', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
MsgBox('請安裝好.Net Framework2.0環境後,再運作本安裝包程式!',mbInformation,MB_OK);
Result := false;
end
else
MsgBox('沒有安裝.Net Framework2.0環境,無法運作XXX程式,本安裝程式即将退出!',mbInformation,MB_OK);
end;
end;
end;
上面這段代碼的作用是通過檢查系統資料庫來判斷客戶機上是否安裝了.Net Framework2.0,如果沒有就從http://www.xxx.com/down/dotnetfx2.exe處下載下傳,并提示使用者安裝下載下傳的.Net Framework2.0的程式之後再安裝本程式。這麼做有一個優點,因為并不是所有的機器都沒有安裝.Net Framework2.0,是以僅僅是一部分沒有安裝的機器才會需要下載下傳,這樣也就不需要将.Net Framework2.0打包進安裝包,是安裝包比較小。
不過這樣在某些情況下也會出現問題,比如開發了一個不錯的軟體,使用者在辦公室裡上網并下載下傳和安裝了這個軟體,覺得不錯,拷貝到家裡沒有上網的機器上時就不能安裝和使用了,這樣麻煩就來了。是以下面想到了另一種解決辦法,這種辦法就是将.Net Framework2.0打包進安裝檔案,在安裝開始之前檢查客戶機上是否安裝了.Net Framework2.0,如果沒有安裝就将.Net Framework2.0安裝檔案從安裝包裡解壓縮出來到臨時檔案夾下并從臨時檔案夾下安裝,否則就直接安裝開發後的軟體,臨時檔案夾下的檔案會在系統重新系統啟動時被自動清理,不用擔心占用磁盤空間。
以下是部分關鍵代碼:
[Files]
.........
Source: "F:\周公的專欄\dotnetfx20.exe"; DestDir: "{tmp}"; Flags: ignoreversion
; 周公的專欄友情提示:dotnetfx20.exe并不會拷貝到安裝後的目錄中,而是在臨時目錄中,這樣重新開機機器之後就會被删除掉
[code]
function CheckDotNet2_0():boolean;
begin
Result:=not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\.NETFramework\policy\v2.0');
end;
function InitializeSetup(): Boolean;
var Path:string;
ResultCode: Integer;
if CheckDotNet2_0() then
begin
ExtractTemporaryFile('dotnetfx20.exe');
Exec(ExpandConstant('{tmp}\dotnetfx20.exe'), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
end;
end;
通過上面的代碼確定了不會将dotnetfx20.exe拷貝到安裝後的檔案夾中,在Visual Studio和InstallShield相信也應該會有這樣的功能,隻是筆者沒有找到,這個功能我覺得比較實用,如果客戶機器上已經安裝了.Net Framework2.0的話不會在安裝時不會感覺到有什麼,如果沒有安裝就會将dotnetfx20.exe釋放到臨時檔案夾下,并從臨時檔案夾下安裝.Net Framework2.0,這樣確定dotnetfx20.exe不會占用安裝檔案夾的空間。這樣制作安裝包的好處是在安裝軟體時無需擔心使用者是否聯網,缺點是使安裝檔案略顯有點大,因為制作的安裝包中要包含一個20多M的dotnetfx20.exe,不過在網速和儲存設備都不是問題的今天,這個不是什麼太大的問題,當然是有點讓人感覺略微地不爽,可能自己開發的軟體才數百K,而必須附帶一個20多M的dotnetfx20.exe。這也是沒有辦法的事情,像早期可以跨*nix和Windows的Java和現在可以跨不同版本的.NET,為了實作在不同平台上有相同的表現,就必須要運作時的支援,正所謂熊掌魚肉不可兼得,雖然有些第三方開發的軟體可以将Java或者.NET平台上的軟體制作成無需運作時支援的exe檔案,但是能否在各個平台上得到一緻的表現,有待考證。
其實這種做法不僅可以用于檢測.Net Framework2.0的情況,也可以用于其它情況,比如檢測.Net Framework3.0或者.Net Framework3.5的情況,特别是當你向朋友展示你開發的WPF應用時;此外,還可以用于部署Java SE項目。
本文轉自周金橋51CTO部落格,原文連結:http://blog.51cto.com/zhoufoxcn/279243 ,如需轉載請自行聯系原作者