NSIS教程(1): 基礎語法
一. 環境搭建
NSIS是“Nullsoft Scriptable Install System”
的簡稱。從http://nsis.sourceforge.net/Download下載NSIS安裝進行安裝,安裝完之後的目錄結構如圖:
可以使用任意文字編輯器(推薦notepad++,帶語法高亮)來開發NSIS指令碼,然後使用makensisw.exe
編譯NSIS指令碼,該工具只提供編譯指令碼的功能,不能對指令碼進行除錯。
二. NSIS指令碼結構
一個NSIS指令碼可以包括安裝程式屬性
、頁面
、區段
等。
對於一個最簡單的NSIS指令碼所必需的是OutFile
屬性(該屬性告訴NSIS編譯生成的安裝包可執行檔案的輸出路徑)和一個區段,如:
OutFile "Simple.exe"
Section "Installer Section"
SectionEnd
儲存上面指令碼到*.nsi檔案,並使用makensisw.exe
開啟編譯,如圖表示編譯成功,成功之後會在腳本當前目錄看到輸出的Simple.exe
;如果編譯失敗,makensisw.exe
會在輸出視窗提示失敗原因。
2.1 安裝程式屬性
安裝程式屬性控制安裝程式的外觀、包括哪個頁面出現在安裝程式裡、在每個頁面的每個部分顯示什麼文字、安裝程式的名稱(如上面指令碼中的OutFile
)、使用什麼樣的圖示、預設安裝目錄、取消什麼樣的檔案等等。
安裝程式屬性可以在除了區段和函式以外的任何地方設定。
可以理解為安裝程式屬性是設定給NSIS編譯器看的,這些屬性值在編譯時都已經確定了,所以除了InstallDir以外,其他安裝程式屬性都不允許使用變數(除了在字串中使用的
$\r
和$\n
)。
NSIS支援的完整安裝程式屬性見:《NSIS使用者手冊 中文版》 的4.8節。
2.2 頁面
頁面分為NSIS內建的嚮導頁面
和使用者自定義頁面
。 一個非靜默安裝程式需要頁面來指導使用者執行安裝程式,可以通過Page
命令或PageEx
(PageEx提供了更多高階的設定)命令來設定哪個頁面顯示。
頁面顯示的順序和它在NSIS指令碼中定義的次序是一致的。
2.2.1 內建嚮導頁面:
NSIS內建的嚮導頁面有:
- license:許可證頁面。
- components: 元件選擇頁面,每個可見的區段都可以作為一個元件給使用者選擇是否安裝。你可以只使用一個區段來構建安裝包,但是如果你想要使用元件頁來讓使用者選擇可選的元件,那你就需要使用多個區段。
- directory: 安裝目錄選擇頁面。
- instfiles: 安裝過程頁面。
- uninstConfirm: 解除安裝確認頁面。
不同的頁面,有不同的屬性。
內建頁面語法如下:
Page (license|components|directory|instfiles|uninstConfirm) [預置函式] [顯示函式] [離開函式]
每個內建的頁面都有三個回撥函式(預置函式、顯示建立函式和離開函式),預置函式在頁面被建立之前被直接的呼叫,顯示函式在頁面被建立後且在顯示之前被直接呼叫,離開函式在使用者按下下一頁按鈕之後並且在頁面離開之前被直接呼叫。
如:
PageEx license
LicenseData "license.rtf" #可以是txt或rtf檔案格式
PageExEnd
2.2.2 自定義頁面
自定義頁面語法:
page custom [建立函式] [離開函式] [標題]
自定義頁面只有兩個回撥函式(建立函式和離開函式),建立函式在需要建立頁面時被呼叫,離開函式在使用者按下下一頁按鈕之後並且在頁面離開之前被直接呼叫。
2.3 區段(Section)
在安裝包裡使用者需要安裝許多東西,如安裝原始碼、附加外掛、指令碼樣例或其他。 裡面的每個安裝元件都有它自己的程式碼塊,當用戶選擇了安裝該元件,那麼安裝程式就會執行對應的程式碼。在NSIS腳本里,這些程式碼稱為區段。每個可見的區段都可以作為一個元件給使用者選擇是否安裝(區段也可以設定屬性對使用者隱藏,預設安裝,讓使用者無法選擇是否安裝)。
NSIS指令碼對區段的數量沒有限制,你可以只使用一個區段來構建安裝包,但是如果你想要使用元件頁來讓使用者選擇可選的元件,那你就需要使用多個區段了。
解除安裝程式也可以有多個區段,但解除安裝程式區段名前要加上字首“un.
”,因為解除安裝程式是要被編譯成是一個單獨的exe的,所以要對編譯器指明哪些內容(如區段)需要被編譯進解除安裝程式。
區段名為空、遺漏或者以一個 “-” 開頭,那麼它將是一個隱藏的區段,使用者也不能在元件遠端頁面選擇禁止它。
三. NSIS語法
3.1 語法概述
- 單行註釋用井號”#”或分號”;”,跨行註釋用可以用C/C++中註釋語法;
- 數字常量可以用十進位制、十六進位制(0x為字首)、八進位制(0為字首)表示,顏色用類似html的中RGB表示法,但去井號”#”。
- 字串常量可以用引號引用,轉意字元用”$\”作字首。美元符號、換行、回車、製表符的NSIS語法表示分別為:
$$
,$\n
,$\r
,$\t
- NSIS指令碼用行尾的反斜槓”\”表示下一行和當前行邏輯上是同一行。
3.2 常量和變數
NSIS對變數和常量都是全域性的,且大小寫敏感的,NSIS中變數和常量都是弱型別的。常用和變數的引用方式都是${VAR_NAME}
或$VAR_NAME
。
使用!define
方式定義常量,如:!define PRODUCT_NAME "網易雲音樂"
,
使用Var
方式定義變數,如:Var a
,
NSIS內建了20個已註冊的變數:$0
~ $9
和 $R0
~ $R9
,這些變數不需要宣告就可以使用,一般用於引數傳遞等。
另外,NSIS內建一個堆疊,使用push
和pop
命令來入棧和出棧,可以使用堆疊來暫存資料。
關於變數的賦值,NSIS中不能直接使用=
來賦值,需要藉助StrCpy
來實現,如:
StrCpy $0 "hello"
StrCpy $0 123
3.3 函式
- 函式定義
Function 函式名
FunctionEnd
函式名以“.”開頭的(例如 “.Whatever”)一般作為回撥函式保留。
函式名以“un.”開頭的函式將會被建立在解除安裝程式裡。因此,普通安裝區段和函式不能呼叫解除安裝函式,而解除安裝區段和解除安裝函式也不能呼叫普通函式。
NSIS函式宣告中不支援引數定義,如果需要傳遞引數,可以使用內建的20個變數或者堆疊的方式。
- 函式呼叫
Call 函式名
3.4 巨集
除了函式之外,NSIS還支援定義巨集
,NSIS中的巨集支援定義引數。
- 巨集定義
!macro 巨集名 [引數1] [引數n]
!macroend
- 巨集呼叫
!insertmacro 巨集名 [引數1] [引數n]
3.5 指令
NSIS內建了很多指令,這些指令提供了安裝包常用了功能,如果這些指令無法滿足需求,使用者也可以自己開發外掛。
NSIS支援的指令列表見:《NSIS使用者手冊 中文版》 的4.9節。
NSIS指令使用中比較特別的在於跳轉,比如執行失敗跳轉到哪裡,成功跳轉到哪裡。
以MessageBox
指令為例([]
為可選項):
MessageBox 訊息框選項列表 訊息框文字 [/SD 返回] [檢測返回值 跳轉到] [檢測返回值2 跳轉到2]
MessageBox MB_ICONQUESTION|MB_YESNO "你確實要完全刪除網易雲音樂,及其所有元件嗎?" /SD IDYES IDYES +2 IDNO +1
上面的用法表示如果MessageBox返回IDYES,則+2,即跳轉到該指令的下2條執行(+1該指令的下1條,+2就為該指令的下2條)。
四. NSIS介面
NSIS提供的介面分為傳統介面(Classic UI)、現代介面(Modern UI)。
4.1 傳統介面
4.2 現代介面
4.3 自定義介面
我們可以使用第三方介面庫(如duilib)自己繪製安裝包的介面,這樣靈活度更大。