NSIS使用教程(安裝包制作安裝文件教程,如何封裝打包文件) 中文版


nsis中文版(Nullsoft Scriptable Install System)是一個專業的開源的可以用來封閉Windows程序的實用工具,是一個開源的 Windows 系統下安裝程序制作程序。nsis它功能強,源碼是直接使用C語言編寫而成,並且可以直接到nsis官網下載所有nsis版本,並且提供了詳細的幫助文檔,方便用戶制作時使用.安裝頁面可以使用Page自定義界面、卸載頁面可以配置讓用戶選擇是否刪除用戶文件、系統設置中對注冊表的操作簡單方便,可以使用REGDLL進行動態庫的注冊,還可以使用諸如EXECWAIT來執行外部程序,還可以用SC等命令或插件來完成服務注冊安裝、提供lzma固實文件解壓縮極強的壓縮性能尤為突出,並且提供上百的插件擴展使得程序編寫更加得心應手,在封裝功能,速度,穩定性等方便更勝一籌。

Nullsoft Scriptable Install System(nsis定制安裝程序)V2.45漢化增強版

NSIS官方網站 http://nsis.sf.net
NSIS開源代碼網址 - 包含NSIS開源代碼及相關作品
NSIS SVN版本控制代碼 - 包含NSIS所有源碼
FAQ - 常見問題列表
NSIS Wiki - 例子、函數、指南、插件、軟件等等
Forum - 發表你的問題或進行 NSIS 相關討論

1.1 代碼注釋

在nsis中可以使用單行注釋,和多行注釋,多行注釋不支持嵌套。:#,;,/**/

#OutFile "注釋.exe"
;Section ""
/*
    MessageBox MB_OK "Hello World!"
SentionEnd
*/

1.2 轉義字符和續行符

轉意字符用"$\"作前綴。美元符號、常用轉意字符換行、回車、制表符的nsi語法表示分別為:$$,$\n,$\r,$\t

nsi腳本用行尾的反斜杠"\"表示下一行和當前行邏輯上是同一行

1.3 互斥運行

調用系統API創建互斥進程

OutFile "Temp.exe"
Section "Temp"
SectionEnd
Function .onInit
InitPluginsDir
  ;創建互斥防止重復運行
  System::Call 'kernel32::CreateMutexA(i 0, i 0, t "Temp") i .r1 ?e'
  Pop $R0
  StrCmp $R0 0 +3
    MessageBox MB_OK|MB_ICONEXCLAMATION "The program is runing!"
    Abort
FunctionEnd

1.4 7-Zip 打開空白

實現7-Zip打開空白

如果你想增加一個有內容的7z壓縮到可執行文件頭部,那么在腳本開始位置增加下面這行代碼就可以了:

!packhdr temp.dat 'cmd /c Copy /B temp.dat /B +外鏈壓縮包.7z temp.dat'

1.5 壓縮資源頭

壓縮資源,直接用資源查看器會提示已加殼,需要先脫殼才能查看資源

!packhdr "exehead.tmp" '"upx.exe" -4 "exehead.tmp"'
 
        

1.6 關於nsis中的變量使用

#程序輸出名稱
OutFile "Variables.exe"
#設置壓縮方式
SetCompress force
SetCompressor /SOLID lzma
#是否進入調試模式
#!define _DEBUG ""
#安裝目錄
!define InstDir "$PROGRAMFILES\Variables"
#壓縮資源
!packhdr "exehead.tmp" '"upx.exe" -4 "exehead.tmp"'
#區段
Section "nsis變量"
    #在安裝過程中改變安裝目錄
    StrCpy "$INSTDIR" "$EXEDIR\Variables"
    #設置輸出目錄
    SetOutPath "$INSTDIR"
    #顯示輸出目錄
    DetailPrint "$OUTDIR"
    #將.(當前目錄)打包和程序,安裝目錄為$INSTDIR
    File /r ".\*.nsi"
    File /r ".\*.7z" 
    
    #輸出當前主程序目錄
    DetailPrint "$EXEDIR"
    #輸出當前使用的語言標記符
    DetailPrint "輸出當前使用的語言標記符$LANGUAGE"
 
#"nsis命令行參數操作"
Call nsis_cmdline
SectionEnd
 
Function nsis_cmdline #"nsis命令行參數操作"
#使用變量$CMDLINE獲得命令行信息
    !ifdef _DEBUG
    MessageBox MB_OK|MB_ICONINFORMATION "$CMDLINE"
    !endif
    DetailPrint "$CMDLINE"
#使用宏來處理命令行信息,它也是基於對$CMDLINE的信息進行處理
    !include FileFunc.nsh
    ${GetParameters} $R0 # 獲得命令行
    ${GetOptions} $R0 "/T"  $R0 # 在命令行里查找是否存在/S選項
    !ifdef _DEBUG
    IfErrors 0 +2
    MessageBox MB_OK "Not found" IDOK +2
    MessageBox MB_OK "Found"
    !endif
    IfErrors 0 +3
    DetailPrint "Not found"
    goto +2
    DetailPrint "Found"
FunctionEnd
這些變量也可以在插件里傳遞,因為他們可以被 DLL 插件讀取和寫入
enum
{
INST_0,         // $0
INST_1,         // $1
INST_2,         // $2
INST_3,         // $3
INST_4,         // $4
INST_5,         // $5
INST_6,         // $6
INST_7,         // $7
INST_8,         // $8
INST_9,         // $9
INST_R0,        // $R0
INST_R1,        // $R1
INST_R2,        // $R2
INST_R3,        // $R3
INST_R4,        // $R4
INST_R5,        // $R5
INST_R6,        // $R6
INST_R7,        // $R7
INST_R8,        // $R8
INST_R9,        // $R9
INST_CMDLINE,   // $CMDLINE
INST_INSTDIR,   // $INSTDIR
INST_OUTDIR,    // $OUTDIR
INST_EXEDIR,    // $EXEDIR
INST_LANG,      // $LANGUAGE
__INST_LAST
};
*/

1.7 關於nsis中的界面制作

#頭文件
!include nsDialogs.nsh
#設置壓縮方式
SetCompressor /SOLID lzma
#支持XP風格
XPStyle on
#標題欄,輸出文件,圖標
Caption "NSIS自定義界面中文版教程"
OutFile "NSIS自定義界面中文版教程.exe"
#變量定義
Var Dialog
Var Image1
#頁面
Page custom page1
#初始化函數
Function .onInit
InitPluginsDir
SetOutPath "$PLUGINSDIR"
File "Image\*.*"
FunctionEnd
#頁面函數
Function page1
nsDialogs::Create /NOUNLOAD 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSd_CreateBitmap} 0 0 100% 100% '全屏圖片'
Pop $Image1
${NSD_SetImage} $Image1 '$PLUGINSDIR\bg.bmp' $1
nsDialogs::show
FunctionEnd
Section "NSIS自定義界面中文版教程"
SectionEnd

1.8 關於nsis中的字符串處理

!include "WordFunc.nsh"
OutFile "關於nsis中的字符串處理.exe"
Var stemp
Section "關於nsis中的字符串處理"
StrCpy $stemp '您的IP地址是:[23.52.1.54]關於nsis中的字符串處理'
${WordFind} "$stemp" "]" "-2{*" $R0
${WordFind} "$R0" "[" "+2*}" $R1
MessageBox MB_OK $R1

Push $stemp
Call GetIP
Pop $R0
MessageBox MB_OK $R0
SectionEnd

Function GetIP
Exch $0
Push $1
Push $2

StrCpy $1 0
IntOp $1 $1 - 1
StrCpy $2 $0 1 $1
StrCmp $2 "]" +2
StrCmp $2 "" 0 -3
StrCpy $0 $0 $1

StrCpy $1 0
IntOp $1 $1 - 1
StrCpy $2 $0 1 $1
StrCmp $2 "[" +2
StrCmp $2 "" 0 -3
IntOp $1 $1 + 1
StrCpy $0 $0 "" $1

Pop $2
Pop $1
Exch $0
FunctionEnd

1.9 關於nsis中的API調用

#頭文件
!include "WordFunc.nsh"
#輸出文件
OutFile "關於nsis中的API調用.exe"
#區段
Section "關於nsis中的API調用"
#獲得磁盤可用空間
StrCpy $0 "D:\"
System::Call kernel32::GetDiskFreeSpaceEx(tr0,*l,*l,*l.r1)
MessageBox MB_OK "$0的可用空間為:$1"
; Create RECT struct

#獲得窗口矩形大小
System::Call `*(i, i, i, i) i .R0`
System::Call `user32::GetClientRect(i $HWNDPARENT, i R0)`
System::Call `*$R0(i.R1, i.R2, i.R3, i.R4) i`
System::Free $R0
MessageBox MB_OK " Left:$R1$\n Top:$R2$\n Right:$R3$\n Bottom:$R4$\n"
SectionEnd

NSIS 常用小問題問答合集

問: 如何用 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 "輸入法安裝失敗"

問: 如何用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 生成的 exe 添加版本信息。
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"
問題就是,能否讓屬性中語言顯示為“中文(中國)”?如附圖:
答: 中文 ID 是 2052。 把 ${LANG_ENGLISH} 改為 2052。

問: 用 2052 之后確實變成“中文(中國)”了。但其他內容仍舊是亂碼,不知有什么辦法可以解決嗎?如附圖:
答: 版本信息設置語句,放在 !insertmacro MUI_LANGUAGE 的后面,NSIS 要注重次序的。如果使用古典界面,放在 LoadLanguageFile "${NSISDIR}\Contrib\Language files\SimpChinese.nlf" 的后面。 

問: 在 NSIS 中如何設置工作目錄,例如一些文件的快捷方式,還有安裝完一個軟件后運行一個程序,而這個程序需要檢測當前工作目錄下的某個文件,這時候設置工作目錄尤為重要,否則程序不能正常運行。
答:NSIS 中設定工作目錄使用 SetOutPath,例如在運行程序的代碼 ExecWait "$INSTDIR\test2.exe" 前放入 SetOutPath $INSTDIR,
那么 $INSTDIR 將會成為當前的工作目錄,建立快捷方式也會把工作目錄設為 $INSTDIR。
  卸載之前運行某程序只需要把運行指令放到 Function un.onInit 里就行。

問: NSIS對於安裝卸載的ICO圖標大小有什么要求?編譯的時候出現以下錯誤提示:
Error finding icon resources: installer, uninstaller icon size mismatch - see the Icon instructions documentation for more information -- failing!
答: 只要保證安裝圖標與卸載圖標大小相同即可。

問: 在安裝的時候不是可以選擇多種語言么?但是我怎樣實現當選擇英文時就裝英文版,選擇中文時就裝中文版?
答: 使用以下腳本:
StrCmp $LANGUAGE ${LANG_SIMPCHINESE} 0 +3
File "你需要安裝的中文文件"
Goto lbl_finish
File "你需要安裝的英文文件"
lbl_finish:

問: 在NSIS中如何才能做到根據對於注冊表鍵值的判斷決定是否寫入字串,如果判斷出某個key存在,則寫入相應的字串,如果不存在,則不寫入字串。例如:我先要判斷 “ HKLM SOFTWARE\nsis”這個key存不存在。如果存在則寫入字串“DispName:nsis”,應該是用“WriteRegStr HKLM "SOFTWARE\nsis" "DispName" "nsis"”。如果不存在這個key,則不寫入注冊表,繼續下面的安裝。
答: 以下代碼實現:
ReadRegStr $0 HKLM SOFTWARE\nsis ""
 IfErrors 0 +2
Goto +2
WriteRegStr HKLM "SOFTWARE\nsis" "DispName" "nsis"

問:NSIS打包軟件安裝完畢后選擇是否重新啟動計算機?
答:第一種方法:
SetRebootFlag true
IfRebootFlag 0 +2
同時如果有!define MUI_FINISHPAGE_NOREBOOTSUPPORT 記得刪掉。
第二種方法:但其實可以跳出窗口詢問
MessageBox MB_YESNO|MB_ICONQUESTION|MB_TOPMOST "請重啟以便補丁安裝完全及垃圾清理完整!" IDNO +2
Reboot

問: 如何運行一個安裝文件 .inf
答: ExecWait "RunDll32 advpack.dll,LaunchINFSection skins.inf,DefaultInstall"

問: 能不能在 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

問: 在安裝過程中按“取消”的話,會彈出是否終止安裝的確認窗口,請問怎樣設置可以讓這個窗口不要出現,按“取消”就直接退出呢?
答: !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

問: 關聯文件圖標后,圖標沒變化。
答: 刷新圖標用:
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

問: 如何屏蔽如下圖中的安裝程序校驗。
答:CRCCheck on|off|force
指定安裝前安裝程序是否對自身執行一個 CRC。注意,如果用戶使用了 /NCRC 命令行參數,且你沒有指定 force 參數時,不會執行 CRC,
這樣有可能導致用戶安裝一個損壞的安裝程序。
安裝程序 CRC 校驗是默認打開的。可以在腳本中用 CRCCheck off 來默認禁止安裝程序的 CRC 校驗。不過這樣做正如解釋上說的可能安裝會出現問題。
作漢化的最好加上校驗,免得安裝程序的問題變成你漢化質量的問題。

問: 記得以前看到有文章介紹過可在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 文件也可以按照此類做法。

問:如何讓NSIS的安裝進度條自動關閉?
答:
SetDetailsPrint none
;這里寫要隱藏的語句
SetDetailsPrint both
相關知識:
  4.8.1.33 ShowInstDetails
  hide|show|nevershow
設置是否顯示安裝詳細信息。你可以設為 hide 來隱藏詳細信息但用戶可以查看,show 用來默認顯示詳細信息,
nevershow 可以阻止用戶查看任何信息。注意區段里可以使用 SetDetailsView 來更改它的設置。

問:用 NSIS 做得安裝程序怎樣能夠添加系統服務啊 還有就是怎樣在安裝了以后服務立刻啟動而不用等到重啟計算機。
答:服務就注冊在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ 下,可以用添加注冊表項的方式添加。

問:我想把一小程序用NSIS打包,但用注冊機算出來的注冊碼保存到注冊表中時是以Hex數據保存的,能否在安裝過程中將輸入到Edit框中的數據轉換成Hex數據保存到注冊表中呢?注冊碼的形式是“XXXX-XXXX-XXXX-XXXX”!
答:試試看這個
!define HKEY_CLASSES_ROOT 0x80000000
!define HKEY_CURRENT_USER 0x80000001
!define HKEY_LOCAL_MACHINE 0x80000002
!define HKEY_USERS 0x80000003
!define HKEY_PERFORMANCE_DATA 0x80000004
!define HKEY_CURRENT_CONFIG 0x80000005
!define HKEY_DYN_DATA 0x80000006
!define ROOT_KEY ${HKEY_CURRENT_USER}
!define SUB_KEY "Software\test"
!define VALUE "KeyValue"
!define DATA "ABC"
System::Call "*(i) i (0) .r0"
System::Call "*(&t1024 '${DATA}') i .r1"
StrLen $2 "${DATA}"
System::Call "Advapi32::RegCreateKey(i ${ROOT_KEY}, t '${SUB_KEY}', i r0) i"
System::Call "*$0(&i8 .r3)"
System::Call "Advapi32::RegSetValueEx(i r3, t '${VALUE}', i 0, i 3, i r1, i r2) i"
System::Call "Advapi32::RegCloseKey(i r0)"
System::Free $1
System::Free $0

問: 比如,我把 a.exe 用nsis包裝好,安裝到 c:\helloLib\a.exe,完成后,想把c:\helloLib\添加到 系統環境變量的 path里頭,這樣,在任何地方輸入 a.exe可執行。如何將路徑添加到 系統環境變量中?
答:以下代碼實現:
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"

問: 如果是這樣寫的時候就可以在左邊顯示頁眉位圖:
!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 就無法顯示位圖,只能出現安裝圖標了,如附圖2。
答: 把插入的headerimage圖片放到右邊(默認是在左邊)
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_RIGHT
!define MUI_HEADERIMAGE_BITMAP "include\resource\modern-header.bmp"
而不是你所說的修改 !define MUI_HEADERIMAGE,應該是在這句下面添加 !define MUI_HEADERIMAGE_RIGHT

問: 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 "正在復制文件..."

 

問: 如何禁止顯示如附圖中的 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 既可避免。

問:NSIS打包時運行程序時不顯示窗口
答:
nsExec::ExecToStack '"$INSTDIR\someprogram.exe" /paramS'
Pop $0 ;;nsExec::ExecToStack 執行結果
Pop $1 ;;someprogram.exe 返回結果
同樣有2個插件
ExecCmd plug-in : http://nsis.sourceforge.net/ExecCmd_plug-in
ExecDos plug-in : http://nsis.sourceforge.net/ExecDos_plug-in

問:NSIS安裝包在安裝完成后打開主頁的代碼
答:
!define MUI_FINISHPAGE_RUN "$INSTDIR\IMETool.exe"
!define MUI_FINISHPAGE_RUN_TEXT "運行程序"
!define MUI_FINISHPAGE_SHOWREADME
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION Info
!define MUI_FINISHPAGE_SHOWREADME_TEXT "打開主頁"
!insertmacro MUI_PAGE_FINISH
Function Info
ExecShell "open" " http://nsis.sf.net/"
Functionend
問:我想在程序安裝完畢時自動運行一個文件,比如批處理文件,網頁文件,可執行文件,之類的東東,具體要怎么做?
答:Function .onInstSuccess中使用ExecWait ''來調命令
問:如何根據對於注冊表鍵值的判斷決定是否寫入字串?
在NSIS中如何才能做到根據對於注冊表鍵值的判斷決定是否寫入字串,如果判斷出某個key存在,則寫入相應的字串,如果不存在,則不寫入字串。例如:我先要判斷“HKLM SOFTWARE\nsis”這個key存不存在。如果存在則寫入字串“DispName:nsis”,應該是用“WriteRegStr HKLM "SOFTWARE\nsis" "DispName" "nsis"”。如果不存在這個key,則不寫入注冊表,繼續下面的安裝。
答:以下代碼可以實現
ReadRegStr $0 HKLM SOFTWARE\nsis ""
 IfErrors 0 +2
 Goto +2
WriteRegStr HKLM "SOFTWARE\nsis" "DispName" "nsis"

問: 組件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 表示獲取某區段的flags狀態(就是是否被勾選,選中返回值為1,反之為0)
SectionGetFlags ${bbb} $0 表示獲取序號為${bbb}的區段的Flags狀態並把返回值輸出到變量 $0,C 區段相同。
接着就是 StrCmp ,解釋同上。
SectionSetFlags ${aaa} 1 表示設置序號為 ${aaa} 區段的 Flags 狀態為 1,即勾選。


問:當字符串長度超過1024時,怎么辦?例如 nsis 里面的語句: RealIniStr $R0 "c:\test.ini" "test" "test"其中 $R0 的長度受 1024 的限制,請問有什么方法可以讀取到2000~3000長度的字符串?
答:到 http://nsis.sourceforge.net/download/specialbuilds/ 下載 Large strings 版的,可以支持到 8196 字節。

問:在nsis中如何注冊 dll、ocx 等文件?
答:nsis 有命令可以注冊 dll、ocx 等文件的
regdll "$instdir\xxx.dll"
unregdll "$instdir\xxx.dll" (反注冊)
上面2個命令建議在 Section(或卸載的 Section) 中運行。
問:我在用NSIS打包一小程序時,需要在卸載時解除Mydll.dll文件的注冊,因此在Section Uninstall的開始處加入了UnRegDLL "$INSTDIR\Mydll.dll" 但卸載后總是達不到預期的效果,該Dll文件的注冊信息不能去掉咯,請問各位大大如何原因啊?
答:這樣應該可以nsexec::exec "regsvr32 /u $INSTDIR\Mydll.dll"


問: 怎么讓 "許可協議"頁面的標題欄,如程序中的“MutliPages 演示”修改為“MutliPages 演示:許可協議”,如附圖。
答: 首先創建一個函數,如下:
Function LicensePagePre
SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:我愛你"
FunctionEnd
然后在協議頁面句子
!insertmacro MUI_PAGE_LICENSE "c:\path\to\licence\YourSoftwareLicence.txt"
之前加入如下語句
!define MUI_PAGE_CUSTOMFUNCTION_PRE LicensePagePre

問: 如何制作安裝包的時候需要調用系統函數來檢測當前安裝包運行的操作系統的內碼頁。
答: 以下代碼顯示系統語言:
System::Call "Kernel32::GetSystemDefaultLangID(v ..) i .s"
Pop $0
IntOp $0 $0 & 0xFFFF
MessageBox MB_OK $0

 
        
// nsis版本
const char *NSIS_VERSION="v2.46";
// 將標准輸出重定向到文件當中
FILE *g_output=stdout;
// 指針的指針**
int main(int argc, char **argv)
/*
#include <stdio.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
    // 定義一個字符指針數組
    char* arr[] = {"hello","world","nsis"};
    // 定義一個指向指針的指針,arr為數組首地址==&arr[0]
    char **ppi = arr;
    // 輸出第2個字符串(ppi+1),從第2個字符開始輸出
    cout << *(ppi+1)+1 << endl; // 結果:"orld"
    // 暫停等待輸入字符回車
    getchar();    
    return 0;
}
*/
// 顯示nsis的版本號
// fprintf格式化數據輸出到一個緩沖區或文件
// fflush清除文件緩沖,文件以寫方式打開時將緩沖區內容寫入文件
  if (argc > 1 && !stricmp(argv[1], "/VERSION"))
  {
    fprintf(g_output,NSIS_VERSION);
    fflush(g_output);
    return 0;
  }
// The /V 開關及后面跟隨的 0 ~ 4 數字設定了輸出。0=無輸出,1=僅錯誤,2=警告和錯誤,3=信息、警告和錯誤,4=全部輸出。
  if (argc > 1 && argv[1][0]=='/' && (argv[1][1]=='v' || argv[1][1]=='V'))
  {
    tmpargpos++;
    if (argv[1][2] <= '2' && argv[1][2] >= '0')
    {
      no_logo=1;
    }
  }
// 代碼中間功能,設置編譯信息,提示信息
// makensis [選項 | script.nsi | - [...]]
/*
選項
/LICENSE 顯示一個許可頁面。
The /V 開關及后面跟隨的 0 ~ 4 數字設定了輸出。0=無輸出,1=僅錯誤,2=警告和錯誤,3=信息、警告和錯誤,4=全部輸出。
The /P 開關及后面跟隨的 0 ~ 5 數字設定編譯程序進程的優先級。 0=空閑, 1=低於正常, 2=正常 (默認), 3=高於正常, 4=高, 5=立即。
The /O 開關及后面跟隨的記錄文件告訴編譯器輸出記錄到記錄文件而不是屏幕。
/PAUSE 使得 makensis 在退出前暫停,當直接從 Windows 執行時非常有用。
/NOCONFIG 禁止包含 nsisconf.nsh 。沒有這個參數的話,安裝程序默認從 nsisconf.nsh 讀取設置。
/CMDHELP 輸出基本的命令用法信息(如果指定了命令),或所有命令(如果未指定命令)。
/HDRINFO 輸出 makensis 編譯的選項信息。
/NOCD 禁止把當前目錄更改到 .nsi 文件。
使用 /D 開關一次或多次將會把符號添加到全局定義列表 (請看 !define)。
使用 /X 開關一次或多次將會執行你隨后指定的代碼。例如: "/XAutoCloseWindow false"
對腳本名指定一個破折號(-)將會通知 Makensis 把標准輸入作為源來使用。
*/
// 調用build.write_output()進行exe文件寫入即生成文件
  if (build.write_output())
  { 
    if (build.display_errors) 
    {
      fprintf(g_output,"Error - aborting creation process\n");
      fflush(g_output);
    }
    return 1;
  }
// 生成主程序 開始輸出信息  
  FILE *fp = fopen(build_output_filename,"w+b");
  if (!fp)
  {
    ERROR_MSG("Can't open output file\n");
    return PS_ERROR;
  }


nsis中文版下載




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM