答:!define MUI_ABORTWARNING 把這句去掉就可以了。
問(wèn):如何將顯示的“setup 將安裝...”中的“setup”去掉,除了用自定義字串來(lái)修改這個(gè)地方以外,如何把這個(gè)setup搞成其他的?比如“安裝程序現(xiàn)在將...”
答:DirText "安裝程序?qū)惭b $(^NameDA) 在下列文件夾。要安裝到不同文件夾,單擊 [瀏覽(B)] 并選擇其他的文件夾。 $_CLICK"
問(wèn):如何定義歡迎頁(yè)面的標(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
問(wèn):添加版本號(hào)
引用內(nèi)容
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 添加版本信息。問(wèn)題就是,能否讓屬性中語(yǔ)言顯示為“中文(中國(guó))”?
答:中文 ID 是 2052。 把 ${LANG_ENGLISH} 改為 2052。
問(wèn):用 2052 之后確實(shí)變成“中文(中國(guó))”了。但其他內(nèi)容仍舊是亂碼,不知有什么辦法可以解決嗎?
答:版本信息設(shè)置語(yǔ)句,放在 !insertmacro MUI_LANGUAGE 的后面,NSIS 要注重次序的。如果使用古典界面,放在 LoadLanguageFile "${NSISDIR}\Contrib\Language files\SimpChinese.nlf" 的后面。
問(wèn):如何禁止顯示 banner 。
答:圖示的效果是因?yàn)榘惭b程序初始化的時(shí)候,也就是 .onInit 函數(shù)里需要用到某個(gè)文件的時(shí)候安裝程序需要搜索整個(gè)數(shù)據(jù)區(qū)塊來(lái)把它解壓出來(lái),當(dāng)安裝程序比較大的時(shí)候搜索比較費(fèi)時(shí),這個(gè)時(shí)候才顯示解壓百分比。一般都是用 ReserveFile 來(lái)避開(kāi)這種搜索。比如 Function .onInit 里有:
程序代碼
InitPluginsDir
File "/oname=$PLUGINSDIR\io.ini" ".\io.ini"
或者其他類(lèi)似的話(huà),安裝程序就需要搜索并解壓這個(gè)文件。一般在腳本頭部加:
程序代碼
ReserveFile ".\io.ini"
這樣 io.ini 就保存在數(shù)據(jù)區(qū)塊的尾部,安裝程序初始化的時(shí)候就不用搜索整個(gè)數(shù)據(jù)區(qū)塊了,相當(dāng)于加快了安裝程序的啟動(dòng)速度。
問(wèn):根據(jù)以上方法使用了,確實(shí)不會(huì)再出現(xiàn)初始化的對(duì)話(huà)框了,但是在自定義的 InstallOptions 頁(yè)顯示前,程序還是會(huì)停頓一段時(shí)間,請(qǐng)問(wèn)這是為何?如何避免?
答:某些控件比較消耗時(shí)間的,比如顯示 ICON、位圖 等,如果 InstallOptions 里含有這些控件可能會(huì)停頓。如果 InstallOptions 是第一個(gè)頁(yè)面的話(huà)還要把 InstallOptions.dll 加入到 ReserveFile 參數(shù)里。再或者就是進(jìn)入 InstallOptions 的時(shí)候含有比較復(fù)雜的指令,比如循環(huán)等。一般在加入 ReserveFile ${NSISDIR}\Plugins\InstallOptions.dll 既可避免。
問(wèn):如何運(yùn)行一個(gè)安裝文件 .inf
答:ExecWait "RunDll32 advpack.dll,LaunchINFSection skins.inf,DefaultInstall"
問(wèn):關(guān)聯(lián)文件圖標(biāo)后,圖標(biāo)沒(méi)變化。
答:刷新圖標(biāo)用, System::Call shell32.dll::SHChangeNotify(l, l, i, i) v (0x08000000, 0, 0, 0)
問(wèn):我用NSIS做好了一個(gè)安裝程序,因?yàn)閿?shù)據(jù)較多,一共有400多M,用的LZMA壓縮方式,做好后的安裝程序約200M,但是我發(fā)現(xiàn)在運(yùn)行這個(gè)安裝程序時(shí)會(huì)在系統(tǒng)TEMP目錄產(chǎn)生一個(gè)同安裝后的全部?jī)?nèi)容同樣大的臨時(shí)文件(一邊運(yùn)行一邊加大,最后到400多M去了),如果我做的程序小倒沒(méi)什么,可是這個(gè)程序有400多M,除了要寫(xiě)入安裝的數(shù)據(jù)外還要同樣大小的空間放臨時(shí)文件,這樣子也實(shí)在是太花不來(lái),我想請(qǐng)問(wèn):有什么辦法能讓其在安裝時(shí)不使用這么多的臨時(shí)空間嗎?安裝的腳本是用HM NIS Edit的向?qū)傻摹?/P>
答:這是因?yàn)?NSIS 在用 LZMA 時(shí)采用了固實(shí)壓縮,何謂固實(shí)壓縮,其實(shí)就是把所有文件統(tǒng)一起來(lái)壓縮,所以這樣壓出來(lái)的文件更加的小,同時(shí)也帶來(lái)了一個(gè)問(wèn)題,安裝解壓的時(shí)候,在臨時(shí)文件夾中生成一個(gè)臨時(shí)文件,隨著安裝的進(jìn)程逐漸增大,到最后,需要臨時(shí)文件會(huì)變成跟原安裝程序一樣大,也就是說(shuō),需要原安裝程序 2 倍的空間才可以安裝這個(gè)程序,所以對(duì)于安裝大量文件時(shí),這是不適合的。
NSIS 2.07 版本之前 LZMA 算法是固實(shí)壓縮的,沒(méi)有非固實(shí)的選項(xiàng),如果需要這樣做,只有下載非固實(shí)壓縮的編譯器,但是 2.07 后的 NSIS 的 LZMA 壓縮已經(jīng)改為默認(rèn)非固實(shí)壓縮了,所以這個(gè)問(wèn)題同時(shí)也不再存在。如果在制作少量文件的安裝時(shí),仍然想取用固實(shí)壓縮可以加入 /SOLID 參數(shù)。
像這樣: SetCompressor /SOLID lzma
問(wèn):能不能在 Section 區(qū)段中實(shí)現(xiàn)讀取INI文件狀態(tài)來(lá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
;選中時(shí)執(zhí)行的代碼
File /a ".\file\fileA.exe"
File /a ".\file\fileB.exe"
${Else}
;不選中時(shí)執(zhí)行的代碼
File /a ".\file\fileA.exe"
${EndIf}
SectionEnd
問(wèn):在 NSIS 中如何設(shè)置工作目錄,例如一些文件的快捷方式,還有安裝完一個(gè)軟件后運(yùn)行一個(gè)程序,而這個(gè)程序需要檢測(cè)當(dāng)前工作目錄下的某個(gè)文件,這時(shí)候設(shè)置工作目錄尤為重要,否則程序不能正常運(yùn)行。
答:NSIS 中設(shè)定工作目錄使用 SetOutPath,例如在運(yùn)行程序的代碼 ExecWait "$INSTDIR\test2.exe" 前放入 SetOutPath $INSTDIR,那么 $INSTDIR 將會(huì)成為當(dāng)前的工作目錄,建立快捷方式也會(huì)把工作目錄設(shè)為 $INSTDIR。卸載之前運(yùn)行某程序只需要把運(yùn)行指令放到 Function un.onInit 里就行
問(wèn):記得以前看到有帖子介紹過(guò)可在NSIS中調(diào)用.inf文件安裝附加驅(qū)動(dòng)程序,具體實(shí)現(xiàn)代碼如下形式:
引用內(nèi)容
ExecWait "RunDll32 advpack.dll,LaunchINFSection drivers.inf,DefaultInstall"
偶在打包一小東東時(shí)使用了這一方法,但遇到的問(wèn)題時(shí),如果在卸載區(qū)段里設(shè)置能自動(dòng)卸載安裝過(guò)的驅(qū)動(dòng)程序呢?
答:能否卸載需要看 INF 文件里面是否有卸載的區(qū)段,例如使用 NSIS 卸載 Windows Messenger 可以這樣:
程序代碼
ExecWait "RunDll32 advpack.dll,LaunchINFSection $windir\INF\msmsgs.inf,BLC.Remove"
關(guān)于 BLC.Remove 的來(lái)源,可以打開(kāi) msmsgs.inf 文件后,能找到名稱(chēng)為 BLC.Remove 的區(qū)段,該區(qū)段用于卸載。區(qū)段的名稱(chēng)是編寫(xiě)者自己定制的。不同的inf文件,區(qū)段名也可能不同。其他的 *.inf 文件也可以按照此類(lèi)做法。
問(wèn):(問(wèn)題如下)
1、我做了一個(gè)可同時(shí)在簡(jiǎn)繁英下執(zhí)行的安裝程序。但有個(gè)很大的困惑。剛開(kāi)始時(shí)做的是簡(jiǎn)體中文版,在簡(jiǎn)中下當(dāng)然沒(méi)問(wèn)題,但在英/繁下,創(chuàng)建的中文程序組名和寫(xiě)注冊(cè)表時(shí)顯示的是亂碼。于是想到寫(xiě)一個(gè)三者皆適合的安裝程序。
我的做法是這樣的,在涉及到創(chuàng)建中文程序組和寫(xiě)注冊(cè)表時(shí),加入一個(gè)判斷,如果英文或繁體,則分別創(chuàng)建英文文件名和big5內(nèi)碼文件名。但在繁體winxp和英文win2k下測(cè)試后,發(fā)現(xiàn)根本無(wú)法正常創(chuàng)建程序組,也無(wú)法正常生成uninstall.exe文件。而寫(xiě)入注冊(cè)表的中文字符,也不能在繁體系統(tǒng)的注冊(cè)表中正常顯示,而是亂碼。
請(qǐng)教高手,這種多語(yǔ)言環(huán)境下該怎么處理,才能正常顯示呢? 總不能全部都給創(chuàng)建成英文的吧?
2、另外有個(gè)小問(wèn)題,如何讓nsis做的安裝程序不顯示具體的安裝文件名,而只顯示“正在復(fù)制文件……”? 象foobar那樣,可惜foobar也有個(gè)顯示詳細(xì)情況的按鈕,我想在復(fù)制文件過(guò)程中完全不顯示和提示被復(fù)制的文件情況。
答:(解答如下)
1、最簡(jiǎn)單的處理辦法就是給需要處理的資源進(jìn)行一個(gè)定義,然后使用 LangString 定義不同的資源。給個(gè)示例:
程序代碼
Caption "$(CAPTION)"
LangString CAPTION ${1033} "DreamMail Installation"
LangString CAPTION ${2052} "DreamMail 安裝向?qū)?
LangString CAPTION ${1028} "DreamMail 桿翾舊"
2、可以使用 DetailPrint ,示例,
程序代碼
DetailPrint "正在復(fù)制文件..."
問(wèn):NSIS對(duì)于安裝卸載的ICO圖標(biāo)大小有什么要求?編譯的時(shí)候出現(xiàn)以下錯(cuò)誤提示:
引用內(nèi)容
Error finding icon resources: installer, uninstaller icon size mismatch - see the Icon instructions documentation for more information -- failing!
答:只要保證安裝圖標(biāo)與卸載圖標(biāo)大小相同即可。
問(wèn):如何屏蔽如下圖中的安裝程序校驗(yàn)。
答:CRCCheck on|off|force 指定安裝前安裝程序是否對(duì)自身執(zhí)行一個(gè) CRC。注意,如果用戶(hù)使用了 /NCRC 命令行參數(shù),且你沒(méi)有指定 force 參數(shù)時(shí),不會(huì)執(zhí)行 CRC,這樣有可能導(dǎo)致用戶(hù)安裝一個(gè)損壞的安裝程序。
安裝程序 CRC 校驗(yàn)是默認(rèn)打開(kāi)的。可以在腳本中用 CRCCheck off 來(lái)默認(rèn)禁止安裝程序的 CRC 校驗(yàn)。不過(guò)這樣做正如解釋上說(shuō)的可能安裝會(huì)出現(xiàn)問(wèn)題。作漢化的最好加上校驗(yàn),免得安裝程序的問(wèn)題變成你漢化質(zhì)量的問(wèn)題。
問(wèn):在安裝的時(shí)候不是可以選擇多種語(yǔ)言么?但是我怎樣實(shí)現(xiàn)當(dāng)選擇英文時(shí)就裝英文版,選擇中文時(shí)就裝中文版?
答:使用以下腳本:
程序代碼
StrCmp $LANGUAGE ${LANG_SIMPCHINESE} 0 +3
File "你需要安裝的中文文件"
Goto lbl_finish
File "你需要安裝的英文文件"
lbl_finish:
問(wèn):組件A 組件B 組件C 均為可選,A可單獨(dú)安裝,B或者C被選擇的時(shí)候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
解釋?zhuān)篠ectionGetFlags 表示獲取某區(qū)段的flags狀態(tài)(就是是否被勾選,選中返回值為1,反之為0)。SectionGetFlags ${bbb} $0 表示獲取序號(hào)為${bbb}的區(qū)段的Flags狀態(tài)并把返回值輸出到變量 $0,C 區(qū)段相同。接著就是 StrCmp ,解釋同上樓。SectionSetFlags ${aaa} 1 表示設(shè)置序號(hào)為 ${aaa} 區(qū)段的 Flags 狀態(tài)為 1,即勾選。
問(wèn):怎么讓“許可協(xié)議”頁(yè)面的標(biāo)題欄,如程序中的“MutliPages 演示”修改為“MutliPages 演示:許可協(xié)議”。
答:首先創(chuàng)建一個(gè)函數(shù),如下。
程序代碼
Function LicensePagePre
SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:我愛(ài)你"
FunctionEnd
然后在協(xié)議頁(yè)面句子
程序代碼
!insertmacro MUI_PAGE_LICENSE "c:\path\to\licence\YourSoftwareLicence.txt"
之前加入如下語(yǔ)句
程序代碼
!define MUI_PAGE_CUSTOMFUNCTION_PRE LicensePagePre
問(wèn):比如,我把 a.exe 用nsis包裝好,安裝到 c:\helloLib\a.exe,完成后,想把c:\helloLib\添加到系統(tǒng)環(huán)境變量的path里頭,這樣,在任何地方輸入a.exe可執(zhí)行。如何將路徑添加到系統(tǒng)環(huán)境變量中?
答:以下代碼實(shí)現(xiàn):
程序代碼
ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path"
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$0;C:\hellolib"
另類(lèi)方法一:寫(xiě)注冊(cè)表,如
程序代碼
[HKEY_CLASSES_ROOT\Applications\a.exe\shell\open\command]
@="yourpath\a.exe"
另類(lèi)方法二:
程序代碼
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\a.exe]
@="c:\helloLib\a.exe"
問(wèn):在NSIS中如何才能做到根據(jù)對(duì)于注冊(cè)表鍵值的判斷決定是否寫(xiě)入字串,如果判斷出某個(gè)key存在,則寫(xiě)入相應(yīng)的字串,如果不存在,則不寫(xiě)入字串。例如:我先要判斷“HKLM SOFTWARE\nsis”這個(gè)key存不存在。如果存在則寫(xiě)入字串“DispName:nsis”,應(yīng)該是用“WriteRegStr HKLM "SOFTWARE\nsis" "DispName" "nsis"”。如果不存在這個(gè)key,則不寫(xiě)入注冊(cè)表,繼續(xù)下面的安裝。
答:以下代碼實(shí)現(xiàn):
程序代碼
ReadRegStr $0 HKLM SOFTWARE\nsis ""
IfErrors 0 +2
Goto +2
WriteRegStr HKLM "SOFTWARE\nsis" "DispName" "nsis"
問(wèn):如何制作安裝包的時(shí)候需要調(diào)用系統(tǒng)函數(shù)來(lái)檢測(cè)當(dāng)前安裝包運(yùn)行的操作系統(tǒng)的內(nèi)碼頁(yè)。
答:以下代碼顯示系統(tǒng)語(yǔ)言:
程序代碼
System::Call "Kernel32::GetSystemDefaultLangID(v ..) i .s"
Pop $0
IntOp $0 $0 & 0xFFFF
MessageBox MB_OK $0
問(wèn):如何用NSIS注冊(cè)字體?
答:以下代碼:
程序代碼
!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 "注冊(cè)字體失敗"
SendMessage ${HWND_BROADcast} ${WM_FONTCHANGE} 0 0
SectionEnd
問(wèn):如何用 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 "輸入法安裝失敗"