問: 在安裝過程中按“取消”的話,會彈出是否終止安裝的確認窗口,請問怎樣設置可以讓這個窗口不要出現,按“取消”就直接退出呢?
答: !define MUI_ABORTWARNING 把這句去掉就可以了....
問: 如圖所示的地方,現在顯示的是“setup 將安裝...”,除了用自定義字串來修改這個地方以外,如何把這個setup搞成其他的?比如“安裝程序現在將...”
答: DirText "安裝程序將安裝 $(^NameDA) 在下列文件夾。要安裝到不同文件夾,單擊 [瀏覽(B)] 并選擇其他的文件夾。 $_CLICK"
問: 如何定義歡迎頁面的標題字體大小。如下圖所示,圖三紅色框內的標題字體。
答: 使用以下腳本
!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 之后確實變成“中文(中國)”了。但其他內容仍舊是亂碼,不知有什么辦法可以解決嗎?如附圖2
答:
版本信息設置語句,放在 !insertmacro MUI_LANGUAGE 的后面,NSIS 要注重次序的。如果使用古典界面,放在
LoadLanguageFile "${NSISDIR}\Contrib\Language files\SimpChinese.nlf"
的后面。
問: 如何禁止顯示如附圖中的 banner 。
答: 圖示的效果是因為安裝程序初始化的時候,也就是 .onInit 函數里需要用到某個文件的時候安裝程序需要搜索整個數據區塊來把它解壓出來,當安裝程序比較大的時候搜索比較費時,這個時候才顯示解壓百分比。一般都是用 ReserveFile 來避開這種搜索。
比如 Function .onInit 里有
InitPluginsDir
File "/oname=$PLUGINSDIR\io.ini" ".\io.ini"
或者其他類似的話,安裝程序就需要搜索并解壓這個文件
一般在腳本頭部加
ReserveFile ".\io.ini"
這樣 io.ini 就保存在數據區塊的尾部,安裝程序初始化的時候就不用搜索整個數據區塊了,相當于加快了安裝程序的啟動速度。
問: 根據以上方法使用了,確實不會再出現初始化的對話框了,但是在自定義的 InstallOptions 頁顯示前,程序還是會停頓一段時間,請問這是為何?如何避免?
答:
某些控件比較消耗時間的,比如顯示 ICON、位圖 等,如果 InstallOptions 里含有這些控件可能會停頓。如果
InstallOptions 是第一個頁面的話還要把 InstallOptions.dll 加入到 ReserveFile
參數里。再或者就是進入 InstallOptions 的時候含有比較復雜的指令,比如循環等。
一般在加入 ReserveFile ${NSISDIR}\Plugins\InstallOptions.dll 既可避免。
問: 如何運行一個安裝文件 .inf
答: ExecWait "RunDll32 advpack.dll,LaunchINFSection skins.inf,DefaultInstall"
問: 關聯文件圖標后,圖標沒變化。
答: 刷新圖標用, System::Call shell32.dll::SHChangeNotify(l, l, i, i) v (0x08000000, 0, 0, 0)
問:
我用NSIS做好了一個安裝程序,因為數據較多,一共有400多M,用的LZMA壓縮方式,做好后的安裝程序約200M,但是我發現在運行這個安裝程序時
會在系統TEMP目錄產生一個同安裝后的全部內容同樣大的臨時文件(一邊運行一邊加大,最后到400多M去了),如果我做的程序小倒沒什么,可是這個程序
有400多M,除了要寫入安裝的數據外還要同樣大小的空間放臨時文件,這樣子也實在是太花不來,
我想請問:有什么辦法能讓其在安裝時不使用這么多的臨時空間嗎?安裝的腳本是用HM NIS Edit的向導生成的。
答:
這是因為 NSIS 在用 LZMA
時采用了固實壓縮,何謂固實壓縮,其實就是把所有文件統一起來壓縮,所以這樣壓出來的文件更加的小,同時也帶來了一個問題,安裝解壓的時候,在臨時文件夾
中生成一個臨時文件,隨著安裝的進程逐漸增大,到最后,需要臨時文件會變成跟原安裝程序一樣大,也就是說,需要原安裝程序 2
倍的空間才可以安裝這個程序,所以對于安裝大量文件時,這是不適合的。
NSIS 2.07 版本之前 LZMA
算法是固實壓縮的,沒有非固實的選項,如果需要這樣做,只有下載非固實壓縮的編譯器,但是 2.07 后的 NSIS 的 LZMA
壓縮已經改為默認非固實壓縮了,所以這個問題同時也不再存在。如果在制作少量文件的安裝時,仍然想取用固實壓縮可以加入 /SOLID 參數。像這樣:
SetCompressor /SOLID lzma
問: 能不能在 Section 區段中實現讀取INI文件狀態來安裝。
如圖所示,若選中單選框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
;選中時執行的代碼
File /a ".\file\fileA.exe"
File /a ".\file\fileB.exe"
${Else}
;不選中時執行的代碼
File /a ".\file\fileA.exe"
${EndIf}
SectionEnd
問: 在 NSIS 中如何設置工作目錄,例如一些文件的快捷方式,還有安裝完一個軟件后運行一個程序,而這個程序需要檢測當前工作目錄下的某個文件,這時候設置工作目錄尤為重要,否則程序不能正常運行。
答:
NSIS 中設定工作目錄使用 SetOutPath,例如在運行程序的代碼 ExecWait "$INSTDIR\test2.exe" 前放入
SetOutPath $INSTDIR,那么 $INSTDIR 將會成為當前的工作目錄,建立快捷方式也會把工作目錄設為 $INSTDIR。
卸載之前運行某程序只需要把運行指令放到 Function un.onInit 里就行
問: 記得以前看到有帖子介紹過可在NSIS中調用.inf文件安裝附加驅動程序,具體實現代碼如下形式:
ExecWait "RunDll32 advpack.dll,LaunchINFSection drivers.inf,DefaultInstall"
偶在打包一小東東時使用了這一方法,但遇到的問題時,如果在卸載區段里設置能自動卸載安裝過的驅動程序呢?
答: 能否卸載需要看 INF 文件里面是否有卸載的區段,例如使用 NSIS 卸載 Windows Messenger 可以這樣:
ExecWait "RunDll32 advpack.dll,LaunchINFSection $windir\INF\msmsgs.inf,BLC.Remove"
關于 BLC.Remove 的來源,可以打開 msmsgs.inf 文件后,能找到名稱為 BLC.Remove 的區段,該區段用于卸載。區段的名稱是編寫者自己定制的。不同的inf文件,區段名也可能不同。
其他的 *.inf 文件也可以按照此類做法。
問: 1. 我做了一個可同時在簡繁英下執行的安裝程序。 但有個很大的困惑。
剛開始時做的是簡體中文版,在簡中下當然沒問題,但在英/繁下,創建的中文程序組名和寫注冊表時顯示的是亂碼。 于是想到寫一個三者皆適合的安裝程序。
我的做法是這樣的,在涉及到創建中文程序組和寫注冊表時,加入一個判斷,如果英文或繁體,則分別創建英文文件名和big5內碼文件名。
但在繁體winxp和英文win2k下測試后,發現根本無法正常創建程序組,也無法正常生成uninstall.exe文件。
而寫入注冊表的中文字符,也不能在繁體系統的注冊表中正常顯示,而是亂碼。
請教高手,這種多語言環境下該怎么處理,才能正常顯示呢? 總不能全部都給創建成英文的吧?
2. 另外有個小問題,如何讓nsis做的安裝程序不顯示具體的安裝文件名,而只顯示“正在復制文件……”? 象foobar那樣,可惜foobar也有個顯示詳細情況的按鈕,我想在復制文件過程中完全不顯示和提示被復制的文件情況。
答: 1. 最簡單的處理辦法就是給需要處理的資源進行一個定義,然后使用 LangString 定義不同的資源。給個示例:
Caption "$(CAPTION)"
LangString CAPTION ${1033} "DreamMail Installation"
LangString CAPTION ${2052} "DreamMail 安裝向導"
LangString CAPTION ${1028} "DreamMail 桿翾舊"
2. 可以使用 DetailPrint ,示例,
DetailPrint "正在復制文件..."
問: NSIS對于安裝卸載的ICO圖標大小有什么要求?編譯的時候出現以下錯誤提示,
Error
finding icon resources: installer, uninstaller icon size mismatch - see
the Icon instructions documentation for more information -- failing!
答: 只要保證安裝圖標與卸載圖標大小相同即可。
問: 如何屏蔽如下圖中的安裝程序校驗。
答: CRCCheck on|off|force
指定安裝前安裝程序是否對自身執行一個 CRC。注意,如果用戶使用了 /NCRC 命令行參數,且你沒有指定 force 參數時,不會執行 CRC,這樣有可能導致用戶安裝一個損壞的安裝程序。
安裝程序 CRC 校驗是默認打開的。可以在腳本中用 CRCCheck off 來默認禁止安裝程序的 CRC 校驗。不過這樣做正如解釋上說的可能安裝會出現問題。作漢化的最好加上校驗,免得安裝程序的問題變成你漢化質量的問題。