大部分人第一次看到NSIS腳本都是一臉懵逼的。因為它這個腳本的結構乍一看上去就非常奇怪,不作說明的話是看不懂的。
編寫腳本命令的時候要非常注意,命令要按照規定寫在腳本中不同的段落里,也就是說,命令的先后順序非常重要。
下面提供了一個標准的簡單的腳本例子,使用注釋說明了每個命令的具體作用,大家如果想快速上手編譯出一個安裝包,直接照着這個例子一行行抄就行了。
# NSIS Modern User Interface
# 關於 Modern 風格界面的命令和宏定義需要參考 NSIS目錄下\Docs\Modern UI 2\Readme.html 這個文件的說明。
# 遇到不懂的命令直接查看手冊即可獲得說明。
# 腳本的段落用 ---- 線進行划分。不同的段落可編寫的命令不同,重點注意。 # Written by Shiroha #-------------------------------- # Includes # 包含需要用到的頭文件,這跟 C 語言是一樣的。 !include "MUI2.nsh" # 使用 Modern 風格界面,也就是大家最熟悉的那種下一步下一步界面。 !include "LogicLib.nsh" # 邏輯操作符頭文件。就是 {If} 那些。 !include "nsProcess.nsh" # 進程控制插件頭文件。用來查找進程和強制結束進程。這個插件可以在 NSIS 官方站點找到下載。 #-------------------------------- # General # 安裝包的基本屬性設置。 # Properly display all languages (Installer will not work on Windows 95, 98 or ME!) Unicode true # 設置為 Unicode 模式,這樣界面才可以顯示全部的語言。 # Name and file Name "$(STR_ProductName)" # 設定軟件的名字。 OutFile "vnr_translate_patch_1.4.0.0.exe" # 設定編譯輸出的文件名。 # Default installation folder InstallDir "" # 設定默認的安裝路徑。 # Allow install to root directory AllowRootDirInstall true # 允許用戶在安裝路徑選擇界面選擇磁盤的根目錄。 # Request application privileges for Windows Vista RequestExecutionLevel user # 設定安裝包需要的用戶權限,只用於 Vista 以上的版本。設置為 admin 編譯出來的 EXE 會帶有盾牌小圖標。 # Show the details by default ShowInstDetails show # 默認顯示安裝細節,安裝過程中輸出的文字信息。 #-------------------------------- # Compiler Flags # 編譯器選項,影響壓縮算法等等。 SetCompressor lzma # 使用 LZMA 壓縮算法,壓縮質量比較好。 SetDateSave off # 不保存文件日期,安裝后文件的日期都是新生成的。 #-------------------------------- # Interface Settings # 界面選項,修改界面上的一些元素。 # The icon for the installer !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-install-alt.ico" # 安裝包使用的圖標文件。MUI_*開頭的宏都定義在 MUI2.nsh 文件里,請查看 Modern UI 2 的說明。 # Sets the text that is shown at the bottom of the install window BrandingText "Provided by Shiroha" # 設置分割線上的文字。 # Bitmap for the Welcome page and the Finish page !define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\nsis3-metro.bmp" # 設置歡迎和完成界面左側的圖片。 # Display a checkbox the user has to check to agree with the license terms !define MUI_LICENSEPAGE_CHECKBOX # 使用復選框來確認安裝協議。 !define MUI_LICENSEPAGE_CHECKBOX_TEXT "$(STR_LicenseAccept)" # 復選框的文字。 # The bitmap with images for the checks of the component select treeview !define MUI_COMPONENTSPAGE_CHECKBITMAP "check.bmp" # 選擇安裝組件界面的復選框圖片,可以自定義的。 # Do not automatically jump to the finish page, to allow the user to check the install log !define MUI_FINISHPAGE_NOAUTOCLOSE # 安裝完成后不要自動跳過過程界面。 # Show a message box with a warning when the user wants to close the installer !define MUI_ABORTWARNING # 中途退出安裝時彈出提示。 # Text for a link on the which the user can click to view a website or file !define MUI_FINISHPAGE_LINK "$(STR_ViewMoreInfo)" # 在完成界面顯示一個鏈接,這個是鏈接上的文本。 # Website or file which the user can select to view using the link !define MUI_FINISHPAGE_LINK_LOCATION "http://tieba.baidu.com/p/6196474861" # 鏈接的實際地址。 # Show all languages, despite user's codepage !define MUI_LANGDLL_ALLLANGUAGES # 強制顯示所有支持的語言。 #-------------------------------- # Installer pages # 安裝包要顯示的界面,需要注意的是,界面是按照插入順序來顯示的。 # Include welcome page !define MUI_PAGE_CUSTOMFUNCTION_LEAVE "OnPageWelcomeLeave" # 這個函數會在點擊歡迎界面的下一步按鈕時調用。 !insertmacro MUI_PAGE_WELCOME # 首先插入的是歡迎界面。 # Create a custom donate page Page custom "OnPageDonateCreate" # 插入一個自定義界面。 # Include license page !insertmacro MUI_PAGE_LICENSE $(STR_License) # 插入協議確認界面。 # Include directory selection page !define MUI_PAGE_CUSTOMFUNCTION_LEAVE "OnPageDirectoryLeave" # 這個函數會在點擊選擇安裝路徑界面的下一步按鈕時調用。 !insertmacro MUI_PAGE_DIRECTORY # 插入選擇安裝路徑界面。 # Include install files page !insertmacro MUI_PAGE_INSTFILES # 插入安裝過程界面。 # Include finish page !insertmacro MUI_PAGE_FINISH # 插入完成界面。 #-------------------------------- # Languages # 定義要支持的語言。 !insertmacro MUI_LANGUAGE "SimpChinese" # 簡體中文,會定義 LANG_SIMPCHINESE 變量。 !insertmacro MUI_LANGUAGE "TradChinese" # 繁體中文,會定義 LANG_TRADCHINESE 變量。 #-------------------------------- # Language strings # 定義一些字符串的多語言版本。 # 使用多語言字符串時要注意用的是小括號,例如 $() 而不是 ${} LangString STR_ProductName ${LANG_SIMPCHINESE} "VNR 翻譯修復補丁 1.4" LangString STR_ProductName ${LANG_TRADCHINESE} "VNR 翻譯修復補丁 1.4" LangString STR_AppIsRunning ${LANG_SIMPCHINESE} "檢測到 VNR 正在運行,請將其退出后再試。" LangString STR_AppIsRunning ${LANG_TRADCHINESE} "檢測到 VNR 正在運行,請將其退出後再試。" LangString STR_DonatePageTitle ${LANG_SIMPCHINESE} "支持作者" LangString STR_DonatePageTitle ${LANG_TRADCHINESE} "支持作者" LangString STR_DonatePageSubTitle ${LANG_SIMPCHINESE} "喵喵喵~" LangString STR_DonatePageSubTitle ${LANG_TRADCHINESE} "喵喵喵~" LicenseLangString STR_License ${LANG_SIMPCHINESE} "license.zh-cn.rtf" LicenseLangString STR_License ${LANG_TRADCHINESE} "license.zh-tw.rtf" LangString STR_LicenseAccept ${LANG_SIMPCHINESE} "我已經備份好這些文件夾(&A)" LangString STR_LicenseAccept ${LANG_TRADCHINESE} "我已經備份好這些資料夾(&A)" LangString STR_WrongInstallDirectory ${LANG_SIMPCHINESE} "你選擇的文件夾不是 VNR 的安裝文件夾,請重新選擇。" LangString STR_WrongInstallDirectory ${LANG_TRADCHINESE} "你選擇的資料夾不是 VNR 的安裝資料夾,請重新選擇。" LangString STR_ViewMoreInfo ${LANG_SIMPCHINESE} "瀏覽貼吧查看更多信息(&M)" LangString STR_ViewMoreInfo ${LANG_TRADCHINESE} "瀏覽貼吧查看更多資訊(&M)" #-------------------------------- # Version Information # 定義輸出的 EXE 文件上的版本信息,也支持多語言顯示。 VIProductVersion "1.4.0.0" VIFileVersion "1.4.0.0" VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "ProductName" "VNR 翻譯修復補丁" VIAddVersionKey /LANG=${LANG_TRADCHINESE} "ProductName" "VNR 翻譯修復補丁" VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "ProductVersion" "1.4.0.0" VIAddVersionKey /LANG=${LANG_TRADCHINESE} "ProductVersion" "1.4.0.0" VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "LegalCopyright" "Shiroha" VIAddVersionKey /LANG=${LANG_TRADCHINESE} "LegalCopyright" "Shiroha" VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "FileDescription" "Application Installer" VIAddVersionKey /LANG=${LANG_TRADCHINESE} "FileDescription" "Application Installer" #-------------------------------- # Reserve Files # 保留特殊的文件,這些文件會單獨壓縮,以便安裝包啟動時快速定位數據並且解壓。 # If you are using solid compression, files that are required before # the actual installation should be stored first in the data block, # because this will make your installer start faster. !insertmacro MUI_RESERVEFILE_LANGDLL # 保留多語言支持插件的DLL文件。 # QR code image file ReserveFile "donate.bmp" # 保留一個自定義圖片文件。 #-------------------------------- # Installer Sections # 定義安裝過程的組件,安裝包至少要有一個組件。如果有多個組件,那就需要定義多個。 # 組件可以定義組件名和執行安裝的優先級。 # 安裝時會按順序執行組件中編寫的命令。 Section # 本安裝包只有一個組件。 # Sets output directory SetOutPath "$INSTDIR" # 設置文件輸出路徑為安裝路徑。 # Files File /r "Files\*.*" # 定義要解包的文件。 # 這個命令比較特殊,他既定義了要打包的文件,也用於在安裝時解包這些文件。 # 這里定義的路徑是要打包的文件的路徑,這里用了通配符來表示 Files 目錄下的所有文件,也可以指定單個文件。 # 安裝時,文件將會解包到 SetOutPath 所設置的路徑。 # 如果 File 命令定義了多個文件,會按目錄結構解包文件,就像平時解壓文件一樣。 SectionEnd #-------------------------------- # Installer Functions # 定義安裝包要用到的所有函數。 # 根據 NSIS 腳本的慣例,函數必須寫在腳本的最后。 Function ".onInit" # 以 “.” 開頭的函數都是內置的回調函數,會在特定時機自動執行。 # 這個函數在安裝包啟動的時候最先執行。 # $PLUGINSDIR will automatically be removed when the installer closes InitPluginsDir # 這個命令用於初始化 $PLUGINSDIR 這個變量,一般路徑是 “用戶臨時目錄\ns隨機字符.tmp\” # Show the language selection dialog !insertmacro MUI_LANGDLL_DISPLAY # 顯示語言選擇對話框。 # Extract QR code image file File "/oname=$PLUGINSDIR\donate.bmp" "donate.bmp" # 把自定義圖片解包到臨時目錄。 FunctionEnd Function "OnPageWelcomeLeave" # 這個函數會在點擊歡迎界面的下一步按鈕時調用。 ${nsProcess::FindProcess} "python.exe" $R0 # 查找名為 “python.exe” 的進程,把結果存到 $R0 寄存器里。 ${If} $R0 != 0 # 如果沒找到,嘗試查找另一個。 ${nsProcess::FindProcess} "pythonw.exe" $R0 # 查找名為 pythonw.exe” 的進程,把結果存到 $R0 寄存器里。 ${If} $R0 != 0 # 如果也沒找到,就可以開始安裝了。 ${nsProcess::Unload} # 這個插件用完之后要手動卸載掉。 Return # 調用返回表示可以進入下一個安裝界面。 ${EndIf} ${EndIf} ${nsProcess::Unload} # 這個插件用完之后要手動卸載掉。 MessageBox MB_ICONEXCLAMATION|MB_OK "$(STR_AppIsRunning)" # 檢查到程序正在運行,彈出一個消息框。 Abort # 調用 Abort 表示不可以進入下一個安裝界面。 FunctionEnd Function "OnPageDonateCreate" # 這個函數會在創建上面定義的界面時調用。 !insertmacro MUI_HEADER_TEXT "$(STR_DonatePageTitle)" "$(STR_DonatePageSubTitle)" # 設定頁面主標題和副標題 nsDialogs::Create 1018 # 創建界面,參數通常固定是“1018”,除非你打算創建很特殊的界面或者對話框。 ${NSD_CreateBitmap} 0 0 100% 100% "" # 創建一個圖片框,左邊是“0,0”大小是“100%,100%”,圖片框的句柄會被壓入棧中。 Pop $R0 # 從棧中彈出圖片框的句柄並存入 $R0 寄存器。 ${NSD_SetImage} $R0 "$PLUGINSDIR\donate.bmp" $R1 # 給圖片框設置一個圖片,並且會返回一個圖片句柄,存入 $R1 寄存器,需要手動釋放。 nsDialogs::Show # 把界面顯示出來。 ${NSD_FreeImage} $R1 # 釋放圖片句柄。 FunctionEnd Function "OnPageDirectoryLeave" # 這個函數會在點擊選擇安裝路徑界面的下一步按鈕時調用。 ${IfNot} ${FileExists} "$INSTDIR\Visual Novel Reader.exe" # 檢查用戶選擇的安裝路徑下是否存在“Visual Novel Reader.exe”這個文件。 MessageBox MB_ICONEXCLAMATION|MB_OK "$(STR_WrongInstallDirectory)" # 不存在說明路徑選擇錯誤,彈出提示框。 Abort # 調用 Abort 表示不可以進入下一個安裝界面。 ${EndIf} FunctionEnd #-------------------------------- # End of script
效果如下:
(語言選擇界面)

(歡迎界面)

(自定義界面)

(協議界面)

(選擇安裝路徑界面)

(安裝過程界面)

(完成界面)

以上腳本只是簡單例子,並不包含在“安裝或卸載程序”登記等需要寫入注冊表的功能,也不包含創建快捷方式的功能,也沒有編寫卸載程序。這個例子只是簡單地將文件解包到指定目錄而已。
如果你看完了這個例子還有諸多不懂,一定要多看 NSIS 安裝目錄下的 Examples 文件夾里的例子,里面的例子演示了各種功能和命令的用法。很快就能學會的。我也就花了一天時間。
