問:我用NSIS做好了一個安裝程序,因為數(shù)據(jù)較多,一共有400多M,用的LZMA壓縮方式,做好后的安裝程序約200M,但是我發(fā)現(xiàn) 在運行這個安裝程序時會在系統(tǒng)TEMP目錄產(chǎn)生一個同安裝后的全部內(nèi)容同樣大的臨時文件(一邊運行一邊加大,最后到400多M去了),如果我做的程序小倒沒什么,可是這個程序有400多M,除了要寫入安裝的數(shù)據(jù)外還要同樣大小的空間放臨時文件,這樣子也實在是太花不來,我想請問:有什么辦法能讓其在安裝時不使用這么多的臨時空間嗎?安裝的腳本是用HM NISEdit的向?qū)傻摹?/font>
答:這是因為 NSIS 在用 LZMA 時采用了固實壓縮,何謂固實壓縮,其實就是把所有文件統(tǒng)一起來壓縮,所以這樣壓出來的文件 更加的小,同時也帶來了一個問題,安裝解壓的時候,在臨時文件夾中生成一個臨時文件,隨著安裝的進程逐漸增大,到最 后,需要臨時文件會變成跟原安裝程序一樣大,也就是說,需要原安裝程序 2 倍的空間才可以安裝這個程序,所以對于安裝大量文件時,這是不適合的。
NSIS 2.07 版本之前 LZMA 算法是固實壓縮的,沒有非固實的選項,如果需要這樣做,只有下載非固實壓縮的編譯器,但 2.07 后的 NSIS 的 LZMA 壓縮已經(jīng)改為默認非固實壓縮了,所以這個問題同時也不再存在。如果在制作少量文件的安裝時,仍然想取用固實壓縮可以加入 /SOLID 參數(shù)。
像這樣: SetCompressor /SOLID lzma
問:能不能在 Section 區(qū)段中實現(xiàn)讀取INI文件狀態(tài)來安裝。若選中單選框1則安裝1中定義的文件。若不選中則不安裝。若選中單選框2則安裝2定義的文件。若不選則不安裝。
答:使用以下代碼
!include LogicLib.nsh
Section -post
SetOutPath $INSTDIR
!insertmacro MUI_INSTALLOPTIONS_READ $INI_VALUE "info.ini" "Field 2" "State"
${If} $INI_VALUE = 1
File /a "./file/fileA.exe"
File /a "./file/fileB.exe"
${EndIf}
!insertmacro MUI_INSTALLOPTIONS_READ $INI_VALUE "info.ini" "Field 3" "State"
${If} $INI_VALUE = 1
File /a "./file/fileA.exe"
${EndIf}
SectionEnd
或者使用以下代碼
程序代碼
!include LogicLib.nsh
Section -post
SetOutPath $INSTDIR
!insertmacro MUI_INSTALLOPTIONS_READ $INI_VALUE "info.ini" "Field 2" "State"
${If} $INI_VALUE = 1
;選中時執(zhí)行的代碼
File /a "./file/fileA.exe"
File /a "./file/fileB.exe"
${Else}
;不選中時執(zhí)行的代碼
File /a "./file/fileA.exe"
${EndIf}
SectionEnd
問:在 NSIS 中如何設(shè)置工作目錄,例如一些文件的快捷方式,還有安裝完一個軟件后運行一個程序,而這個程序需要檢測當前工作目錄下的某個文件,這時候設(shè)置工作目錄尤為重要,否則程序不能正常運行。
答:NSIS 中設(shè)定工作目錄使用 SetOutPath,例如在運行程序的代碼 ExecWait "$INSTDIR/test2.exe" 前放入 SetOutPath $INSTDIR,那么 $INSTDIR 將會成為當前的工作目錄,建立快捷方式也會把工作目錄設(shè)為 $INSTDIR。卸載之前運行某程序只需要把運行指令放到 Function un.onInit 里就行
問:記得以前看到有帖子介紹過可在NSIS中調(diào)用.inf文件安裝附加驅(qū)動程序,具體實現(xiàn)代碼如下形式:
ExecWait "RunDll32 advpack.dll,LaunchINFSection drivers.inf,DefaultInstall"
問:偶在打包一小東東時使用了這一方法,但遇到的問題時,如果在卸載區(qū)段里設(shè)置能自動卸載安裝過的驅(qū)動程序呢?
答:能否卸載需要看 INF 文件里面是否有卸載的區(qū)段,例如使用 NSIS 卸載 Windows Messenger 可以這樣:
程序代碼
ExecWait "RunDll32 advpack.dll,LaunchINFSection $windir/INF/msmsgs.inf,BLC.Remove"
關(guān)于 BLC.Remove 的來源,可以打開 msmsgs.inf 文件后,能找到名稱為 BLC.Remove 的區(qū)段,該區(qū)段用于卸載。區(qū)段的 名稱是編寫者自己定制的。不同的inf文件,區(qū)段名也可能不同。其他的 *.inf 文件也可以按照此類做法。
問:(問題如下)
1、我做了一個可同時在簡繁英下執(zhí)行的安裝程序。但有個很大的困惑。剛開始時做的是簡體中文版,在簡中下當然沒問題, 但在英/繁下,創(chuàng)建的中文程序組名和寫注冊表時顯示的是亂碼。于是想到寫一個三者皆適合的安裝程序。我的做法是這樣的,在涉及到創(chuàng)建中文程序組和寫注冊表時,加入一個判斷,如果英文或繁體,則分別創(chuàng)建英文文件名和big5內(nèi)碼文件名。但在繁體winxp和英文win2k下測試后,發(fā)現(xiàn)根本無法正常創(chuàng)建程序組,也無法正常生成uninstall.exe文件。而寫入注冊表的中文字符,也不能在繁體系統(tǒng)的注冊表中正常顯示,而是亂碼。請教高手,這種多語言環(huán)境下該怎么處理,才能正常顯示呢? 總不能全部都給創(chuàng)建成英文的吧?
2、另外有個小問題,如何讓nsis做的安裝程序不顯示具體的安裝文件名,而只顯示“正在復(fù)制文件……”?象foobar那樣,可惜foobar也有個顯示詳細情況的按鈕,我想在復(fù)制文件過程中完全不顯示和提示被復(fù)制的文件情況。
答:(解答如下)
1、最簡單的處理辦法就是給需要處理的資源進行一個定義,然后使用 LangString 定義不同的資源。給個示例:
程序代碼