NSIS 常用小問題合集[轉(zhuǎn)]
Posted on 2007-12-22 11:13 Matthew Chen 閱讀(1080) 評論(3) 編輯 收藏 所屬分類: Softwares Configurations轉(zhuǎn)自: http://www.hanzify.org/teach/index.php?Go=Show::500-1126800000
附圖:

附圖:

附圖:


附圖:

附圖:

附圖:

附圖1:

附圖2:

附圖:

問: 在安裝過程中按“取消”的話,會彈出是否終止安裝的確認(rèn)窗口,請問怎樣設(shè)置可以讓這個窗口不要出現(xiàn),按“取消”就直接退出呢? 答: !define MUI_ABORTWARNING 把這句去掉就可以了.... |
問: 如圖所示的地方,現(xiàn)在顯示的是“setup 將安裝...”,除了用自定義字串來修改這個地方以外,如何把這個setup搞成其他的?比如“安裝程序現(xiàn)在將...” 答: DirText "安裝程序?qū)惭b $(^NameDA) 在下列文件夾。要安裝到不同文件夾,單擊 [瀏覽(B)] 并選擇其他的文件夾。 $_CLICK" |
附圖:

問: 如何定義歡迎頁面的標(biāo)題字體大小。如下圖所示,圖三紅色框內(nèi)的標(biāo)題字體。 答: 使用以下腳本 !define MUI_PAGE_CUSTOMFUNCTION_SHOW ChageFONT !insertmacro MUI_PAGE_WELCOME Function ChageFONT GetDlgItem $0 $MUI_HWND 1201 createFont $1 "Tahoma" "11" "700" SendMessage $0 ${WM_SETFONT} $1 0 FunctionEnd |
附圖:
問: 添加版本號 VIProductVersion "1.2.3.4" VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "Test Application" VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "A test comment" VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "Fake company" VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" "Test Application is a trademark of Fake company" VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "?Fake company" VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "Test Application" VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "1.2.3" 在腳本中加入上面的代碼,則為 NSIS 生成的 exe 添加版本信息。 問題就是,能否讓屬性中語言顯示為“中文(中國)”?如附圖1 答: 中文 ID 是 2052。 把 ${LANG_ENGLISH} 改為 2052。 問: 用 2052 之后確實變成“中文(中國)”了。但其他內(nèi)容仍舊是亂碼,不知有什么辦法可以解決嗎?如附圖2 答: 版本信息設(shè)置語句,放在 !insertmacro MUI_LANGUAGE 的后面,NSIS 要注重次序的。如果使用古典界面,放在 LoadLanguageFile "${NSISDIR}\Contrib\Language files\SimpChinese.nlf" 的后面。 |
附圖:
問: 如何禁止顯示如附圖中的 banner 。 答: 圖示的效果是因為安裝程序初始化的時候,也就是 .onInit 函數(shù)里需要用到某個文件的時候安裝程序需要搜索整個數(shù)據(jù)區(qū)塊來把它解壓出來,當(dāng)安裝程序比較大的時候搜索比較費時,這個時候才顯示解壓百分比。一般都是用 ReserveFile 來避開這種搜索。 比如 Function .onInit 里有 InitPluginsDir File "/oname=$PLUGINSDIR\io.ini" ".\io.ini" 或者其他類似的話,安裝程序就需要搜索并解壓這個文件 一般在腳本頭部加 ReserveFile ".\io.ini" 這樣 io.ini 就保存在數(shù)據(jù)區(qū)塊的尾部,安裝程序初始化的時候就不用搜索整個數(shù)據(jù)區(qū)塊了,相當(dāng)于加快了安裝程序的啟動速度。 問: 根據(jù)以上方法使用了,確實不會再出現(xiàn)初始化的對話框了,但是在自定義的 InstallOptions 頁顯示前,程序還是會停頓一段時間,請問這是為何?如何避免? 答: 某些控件比較消耗時間的,比如顯示 ICON、位圖 等,如果 InstallOptions 里含有這些控件可能會停頓。如果 InstallOptions 是第一個頁面的話還要把 InstallOptions.dll 加入到 ReserveFile 參數(shù)里。再或者就是進(jìn)入 InstallOptions 的時候含有比較復(fù)雜的指令,比如循環(huán)等。 一般在加入 ReserveFile ${NSISDIR}\Plugins\InstallOptions.dll 既可避免。 |
附圖:
問: 如何運(yùn)行一個安裝文件 .inf 答: ExecWait "RunDll32 advpack.dll,LaunchINFSection skins.inf,DefaultInstall" |
問: 關(guān)聯(lián)文件圖標(biāo)后,圖標(biāo)沒變化。 答: 刷新圖標(biāo)用, System::Call shell32.dll::SHChangeNotify(l, l, i, i) v (0x08000000, 0, 0, 0) |
問: 我用NSIS做好了一個安裝程序,因為數(shù)據(jù)較多,一共有400多M,用的LZMA壓縮方式,做好后的安裝程序約200M,但是我發(fā)現(xiàn)在運(yùn)行這個安裝程序時會在系統(tǒng)TEMP目錄產(chǎn)生一個同安裝后的全部內(nèi)容同樣大的臨時文件(一邊運(yùn)行一邊加大,最后到400多M去了),如果我做的程序小倒沒什么,可是這個程序有400多M,除了要寫入安裝的數(shù)據(jù)外還要同樣大小的空間放臨時文件,這樣子也實在是太花不來, 我想請問:有什么辦法能讓其在安裝時不使用這么多的臨時空間嗎?安裝的腳本是用HM NIS Edit的向?qū)傻摹?br /> 答: 這是因為 NSIS 在用 LZMA 時采用了固實壓縮,何謂固實壓縮,其實就是把所有文件統(tǒng)一起來壓縮,所以這樣壓出來的文件更加的小,同時也帶來了一個問題,安裝解壓的時候,在臨時文件夾中生成一個臨時文件,隨著安裝的進(jìn)程逐漸增大,到最后,需要臨時文件會變成跟原安裝程序一樣大,也就是說,需要原安裝程序 2 倍的空間才可以安裝這個程序,所以對于安裝大量文件時,這是不適合的。 NSIS 2.07 版本之前 LZMA 算法是固實壓縮的,沒有非固實的選項,如果需要這樣做,只有下載非固實壓縮的編譯器,但是 2.07 后的 NSIS 的 LZMA 壓縮已經(jīng)改為默認(rèn)非固實壓縮了,所以這個問題同時也不再存在。如果在制作少量文件的安裝時,仍然想取用固實壓縮可以加入 /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è)置工作目錄,例如一些文件的快捷方式,還有安裝完一個軟件后運(yùn)行一個程序,而這個程序需要檢測當(dāng)前工作目錄下的某個文件,這時候設(shè)置工作目錄尤為重要,否則程序不能正常運(yùn)行。 答: NSIS 中設(shè)定工作目錄使用 SetOutPath,例如在運(yùn)行程序的代碼 ExecWait "$INSTDIR\test2.exe" 前放入 SetOutPath $INSTDIR,那么 $INSTDIR 將會成為當(dāng)前的工作目錄,建立快捷方式也會把工作目錄設(shè)為 $INSTDIR。 卸載之前運(yùn)行某程序只需要把運(yùn)行指令放到 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í)行的安裝程序。 但有個很大的困惑。 剛開始時做的是簡體中文版,在簡中下當(dāng)然沒問題,但在英/繁下,創(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也有個顯示詳細(xì)情況的按鈕,我想在復(fù)制文件過程中完全不顯示和提示被復(fù)制的文件情況。 答: 1. 最簡單的處理辦法就是給需要處理的資源進(jìn)行一個定義,然后使用 LangString 定義不同的資源。給個示例: Caption "$(CAPTION)" LangString CAPTION ${1033} "DreamMail Installation" LangString CAPTION ${2052} "DreamMail 安裝向?qū)? LangString CAPTION ${1028} "DreamMail 桿翾舊" 2. 可以使用 DetailPrint ,示例, DetailPrint "正在復(fù)制文件..." |
問: NSIS對于安裝卸載的ICO圖標(biāo)大小有什么要求?編譯的時候出現(xiàn)以下錯誤提示, Error finding icon resources: installer, uninstaller icon size mismatch - see the Icon instructions documentation for more information -- failing! 答: 只要保證安裝圖標(biāo)與卸載圖標(biāo)大小相同即可。 |
問: 如何屏蔽如下圖中的安裝程序校驗。 答: CRCCheck on|off|force 指定安裝前安裝程序是否對自身執(zhí)行一個 CRC。注意,如果用戶使用了 /NCRC 命令行參數(shù),且你沒有指定 force 參數(shù)時,不會執(zhí)行 CRC,這樣有可能導(dǎo)致用戶安裝一個損壞的安裝程序。 安裝程序 CRC 校驗是默認(rèn)打開的。可以在腳本中用 CRCCheck off 來默認(rèn)禁止安裝程序的 CRC 校驗。不過這樣做正如解釋上說的可能安裝會出現(xiàn)問題。作漢化的最好加上校驗,免得安裝程序的問題變成你漢化質(zhì)量的問題。 |
附圖:
問: 在安裝的時候不是可以選擇多種語言么?但是我怎樣實現(xiàn)當(dāng)選擇英文時就裝英文版,選擇中文時就裝中文版? 答: 使用以下腳本, StrCmp $LANGUAGE ${LANG_SIMPCHINESE} 0 +3 File "你需要安裝的中文文件" Goto lbl_finish File "你需要安裝的英文文件" lbl_finish: |
問: 組件A 組件B 組件C 均為可選,A可單獨安裝,B或者C被選擇的時候A必須被選擇 答: 以下代碼, Section "組件 A" aaa detailprint "A" SectionEnd Section "組件 B" bbb detailprint "B" SectionEnd Section "組件 C" ccc detailprint "C" SectionEnd Function .onSelChange SectionGetFlags ${bbb} $0 SectionGetFlags ${ccc} $1 IntOp $0 $0 & 1 IntOp $1 $1 & 1 IntCmp $0 1 0 +2 SectionSetFlags ${aaa} 1 IntCmp $1 1 0 +2 SectionSetFlags ${aaa} 1 FunctionEnd 解釋:SectionGetFlags 表示獲取某區(qū)段的flags狀態(tài)(就是是否被勾選,選中返回值為1,反之為0) SectionGetFlags ${bbb} $0 表示獲取序號為${bbb}的區(qū)段的Flags狀態(tài)并把返回值輸出到變量 $0,C 區(qū)段相同。 接著就是 StrCmp ,解釋同上樓。 SectionSetFlags ${aaa} 1 表示設(shè)置序號為 ${aaa} 區(qū)段的 Flags 狀態(tài)為 1,即勾選。 |
問: 如果是這樣寫的時候就可以在左邊顯示頁眉位圖 !define MUI_ABORTWARNING !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_BITMAP "f:\11.bmp" 會顯示如附圖1。會靠左,但是如果把 MUI_HEADERIMAGE 換成 MUI_HEADERIMAGE_RIGHT 就無法顯示位圖,只能出現(xiàn)安裝圖標(biāo)了,如附圖2。 答: 把插入的headerimage圖片放到右邊(默認(rèn)是在左邊) !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_RIGHT !define MUI_HEADERIMAGE_BITMAP "include\resource\modern-header.bmp" 而不是你所說的修改 !define MUI_HEADERIMAGE,應(yīng)該是在這句下面添加 !define MUI_HEADERIMAGE_RIGHT |
附圖1:
附圖2:
問: 怎么讓 "許可協(xié)議"頁面的標(biāo)題欄,如程序中的“MutliPages 演示”修改為“MutliPages 演示:許可協(xié)議”,如附圖。 答: 首先創(chuàng)建一個函數(shù),如下。 Function LicensePagePre SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:我愛你" FunctionEnd 然后在協(xié)議頁面句子 !insertmacro MUI_PAGE_LICENSE "c:\path\to\licence\YourSoftwareLicence.txt" 之前加入如下語句 !define MUI_PAGE_CUSTOMFUNCTION_PRE LicensePagePre |
附圖:
問: 比如,我把 a.exe 用nsis包裝好,安裝到 c:\helloLib\a.exe,完成后,想把c:\helloLib\添加到 系統(tǒng)環(huán)境變量的 path里頭,這樣,在任何地方輸入 a.exe可執(zhí)行。如何將路徑添加到 系統(tǒng)環(huán)境變量中? 答:以下代碼實現(xiàn): ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$0;C:\hellolib" 另類方法一: 寫注冊表,如 [HKEY_CLASSES_ROOT\Applications\a.exe\shell\open\command] @="yourpath\a.exe" 另類方法二: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\a.exe] @="c:\helloLib\a.exe" |
問: 在NSIS中如何才能做到根據(jù)對于注冊表鍵值的判斷決定是否寫入字串,如果判斷出某個key存在,則寫入相應(yīng)的字串,如果不存在,則不寫入字串。例如:我先要判斷 “ HKLM SOFTWARE\nsis”這個key存不存在。如果存在則寫入字串“DispName:nsis”,應(yīng)該是用“WriteRegStr HKLM "SOFTWARE\nsis" "DispName" "nsis"”。如果不存在這個key,則不寫入注冊表,繼續(xù)下面的安裝。 答: 以下代碼實現(xiàn), ReadRegStr $0 HKLM SOFTWARE\nsis "" IfErrors 0 +2 Goto +2 WriteRegStr HKLM "SOFTWARE\nsis" "DispName" "nsis" |
問: 如何制作安裝包的時候需要調(diào)用系統(tǒng)函數(shù)來檢測當(dāng)前安裝包運(yùn)行的操作系統(tǒng)的內(nèi)碼頁。 答: 以下代碼顯示系統(tǒng)語言 System::Call "Kernel32::GetSystemDefaultLangID(v ..) i .s" Pop $0 IntOp $0 $0 & 0xFFFF MessageBox MB_OK $0 |
問: 如何用NSIS注冊字體? 答: 以下代碼, !include WinMessages.nsh Section "MainSection" SEC01 File /oname=$FONTS\tahoma.ttf tahoma.ttf Push "$FONTS\tahoma.ttf" System::Call "Gdi32::AddFontResource(t s) i .s" Pop $0 IntCmp $0 0 0 +2 +2 MessageBox MB_OK "注冊字體失敗" SendMessage ${HWND_BROADcast} ${WM_FONTCHANGE} 0 0 SectionEnd |
問: 如何用 NSIS 安裝輸入法。 答: 以下代碼, SetOutPath $SYSDIR File WBIME.ime Push "五筆輸入法" Push "$SYSDIR\WBIME.ime" System::Call "Imm32::ImmInstallIME(t s, t s) i .s" System::Call "Imm32::ImmIsIME(i s) i .s" Pop $0 IntCmp $0 1 0 +3 +3 MessageBox MB_OK "輸入法安裝成功" Goto +2 MessageBox MB_OK "輸入法安裝失敗" |