簡介
NSIS(Nullsoft Scriptable Install System)是一個開源的 Windows 系統下安裝程序制作程序。它提供了安裝、卸載、系統設置、文件解壓縮等功能。這如其名字所指出的那樣,NSIS 是通過它的腳本語言來描述安裝程序的行為和邏輯的。NSIS 的腳本語言和通常的編程語言有類似的結構和語法,但它是為安裝程序這類應用所設計的。
工具:
HW VNISEdit(NSIS腳本編輯器)
1、 使用編輯器中NSIS腳本向導功能,自動生成對應的nsi腳本。
點擊文件->新建腳本:向導,接下來根據向導頁面的設置選項一步步設置你需要的安裝條件。
2、也可以在編輯器中編寫nsi腳本,然后再編譯生成exe安裝包文件。
腳本結構
NSIS腳本(下稱nsi腳本)主要包含安裝程序屬性、頁面、區段、函數。
屬性
用來定義安裝程序的行為和界面風格,這些屬性大部分是編譯時刻屬性,即不能在運行時刻改變。
頁面
安裝程序的向導頁面
例:
Page license Page components Page directory Page instfiles UninstPage uninstConfirm UninstPage instfiles |
區段
是對應某種安裝/卸載選項的處理邏輯,該段代碼僅當用戶選擇相應的選項才被執行。卸載程序的區段名用"un."作為前綴。
例:
Section "Installer Section" SectionEnd
Section "un.Uninstaller Section" SectionEnd |
區段名的修飾符/o表示該區段默認不選上,-表示隱藏區段(匿名區段也是隱藏區段),!表示需要粗體顯示的區段。
SectionIn表示該區段和安裝類型之間的關系
SubSection表示子區段
SectionIn insttype_index [insttype_index] ... [RO] ;RO修飾符表示不可修改。 SubSection [/e] Caption [subsection_name index output] ;修飾符/e用於該子區段的所有區段是否默認展開。 |
函數
包含了模塊化的安裝邏輯。
在nsi腳本中函數分為兩種:用戶自定義函數和回調函數。
用戶自定義函數
用戶自定義函數僅當是Call指令調用時才被執行,如果函數體中沒有abort語句,則安裝程序執行完了用戶自定義函數,繼續運行Call語句和指令。
用戶自定義函數的語法:
Function <函數名> # some commands FunctionEn |
回調函數
回調函數則是由在特定的時間點觸發的程序段。
例:
Function .onInit MessageBox MB_YESNO "This will install My Program. Do you wish to continue?" IDYES gogogo Abort gogogo: FunctionEnd |
安裝邏輯回調函數
NSIS對於安裝邏輯定義以下回調函數:
.onGUIInit、.onInit、.onInstFailed、.onInstSuccess、.onGUIEnd、.onMouseOverSection、.onRebootFailed、.onSelChange、.onUserAbort、.onVerifyInstDir
卸載邏輯回調函數
NSIS對於卸載邏輯定義以下回調函數:
un.onGUIInit、un.onInit、un.onUninstFailed、un.onUninstSuccess、un.onGUIEnd、un.onRebootFailed、un.onUserAbort
基本語法
變量
nsi腳本用var關鍵字來定義變量,使用$來引用變量。
注意:變量是全局的並且是大小寫敏感的。
除了用戶自定義的變量外,nsi腳本中定義了寄存器變量$0~$9,$R0~$R9用於參數傳遞,以及系統變量用於特定用途,這些變量主要有:
$INSTDIR
用戶定義的解壓路徑。
$PROGRAMFILES
程序文件目錄(通常為 C:\Program Files 但是運行時會檢測)。
$COMMONFILES
公用文件目錄。這是應用程序共享組件的目錄(通常為 C:\Program Files\Common Files 但是運行時會檢測)。
$DESKTOP
Windows 桌面目錄(通常為 C:\windows\desktop 但是運行時會檢測)。該常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
$EXEDIR
安裝程序運行時的位置。(從技術上來說你可以修改改變量,但並不是一個好方法)。
${NSISDIR}
包含 NSIS 安裝目錄的一個標記。在編譯時會檢測到。常用於在你想調用一個在 NSIS 目錄下的資源時,例如:圖標、界面……
$WINDIR
Windows 目錄(通常為 C:\windows 或 C:\winnt 但在運行時會檢測)
$SYSDIR
Windows 系統目錄(通常為 C:\windows\system 或 C:\winnt\system32 但在運行時會檢測)
$TEMP
系統臨時目錄(通常為 C:\windows\temp 但在運行時會檢測)
$STARTMENU
開始菜單目錄(常用於添加一個開始菜單項,使用 CreateShortCut)。該常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
$SMPROGRAMS
開始菜單程序目錄(當你想定位 $STARTMENU\程序 時可以使用它)。該常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
$SMSTARTUP
開始菜單程序/啟動 目錄。該常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
$QUICKLAUNCH
在 IE4 活動桌面及以上的快速啟動目錄。如果快速啟動不可用,僅僅返回和 $TEMP 一樣。
$DOCUMENTS
文檔目錄。一個當前用戶典型的路徑形如 C:\Documents and Settings\Foo\My Documents。這個常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
該常量在 Windows 95 且 Internet Explorer 4 沒有安裝時無效。
$SENDTO
該目錄包含了“發送到”菜單快捷項。
$RECENT
該目錄包含了指向用戶最近文檔的快捷方式。
$FAVORITES
該目錄包含了指向用戶網絡收藏夾、文檔等的快捷方式。這個常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
該常量在 Windows 95 且 Internet Explorer 4 沒有安裝時無效。
$MUSIC
用戶的音樂文件目錄。這個常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
該常量僅在 Windows XP、ME 及以上才有效。
$PICTURES
用戶的圖片目錄。這個常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
該常量僅在 Windows 2000、XP、ME 及以上才有效。
$VIDEOS
用戶的視頻文件目錄。這個常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
該常量僅在 Windows XP、ME 及以上才有效。
$NETHOOD
該目錄包含了可能存在於我的網絡位置、網上鄰居文件夾的鏈接對象。
該常量在 Windows 95 且 Internet Explorer 4 和活動桌面沒有安裝時無效。
$FONTS
系統字體目錄。
$TEMPLATES
文檔模板目錄。這個常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
$APPDATA
應用程序數據目錄。當前用戶路徑的檢測需要 Internet Explorer 4 及以上。所有用戶路徑的檢測需要 Internet Explorer 5 及以上。這個常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
該常量在 Windows 95 且 Internet Explorer 4 和活動桌面沒有安裝時無效。
$PRINTHOOD
該目錄包含了可能存在於打印機文件夾的鏈接對象。
該常量在 Windows 95 和 Windows 98 上無效。
$INTERNET_CACHE
Internet Explorer 的臨時文件目錄。
該常量在 Windows 95 和 Windows NT 且 Internet Explorer 4 和活動桌面沒有安裝時無效。
$COOKIES
Internet Explorer 的 Cookies 目錄。
該常量在 Windows 95 和 Windows NT 且 Internet Explorer 4 和活動桌面沒有安裝時無效。
$HISTORY
Internet Explorer 的歷史記錄目錄。
該常量在 Windows 95 和 Windows NT 且 Internet Explorer 4 和活動桌面沒有安裝時無效。
$PROFILE
用戶的個人配置目錄。一個典型的路徑如 C:\Documents and Settings\Foo。
該常量在 Windows 2000 及以上有效。
$ADMINTOOLS
一個保存管理工具的目錄。這個常量的內容(所有用戶或當前用戶)取決於 SetShellVarContext 設置。默認為當前用戶。
該常量在 Windows 2000、ME 及以上有效。
$RESOURCES
該資源目錄保存了主題和其他 Windows 資源(通常為 C:\Windows\Resources 但在運行時會檢測)。
該常量在 Windows XP 及以上有效。
$RESOURCES_LOCALIZED
該本地的資源目錄保存了主題和其他 Windows 資源(通常為 C:\Windows\Resources\1033 但在運行時會檢測)。
該常量在 Windows XP 及以上有效。
$CDBURN_AREA
一個在燒錄 CD 時儲存文件的目錄。.
該常量在 Windows XP 及以上有效。
$HWNDPARENT
父窗口的十進制 HWND。
$PLUGINSDIR
該路徑是一個臨時目錄,當第一次使用一個插件或一個調用 InitPluginsDir 時被創建。該文件夾當解壓包退出時會被自動刪除。這個文件夾的用意是用來保存給 InstallOptions 使用的 INI 文件、啟動畫面位圖或其他插件運行需要的文件。
編譯器指令
nsi腳本的編譯器指令主要指僅在編譯時刻執行的命令。這些命令主要用來包含文件、條件化編譯、定義常量、定義宏等。定義常量和宏是編譯器指令的最主要應用。
常用指令
文件、目錄操作
File
作用:釋放文件到當前輸出路徑。
如果使用了 /nonfatal 開關且當文件未找到時使用警告來代替錯誤
如果使用了 /a 開關,則被添加的文件的屬性將會保持
如果使用了 /r 開關,匹配的文件將會在子目錄里被遞歸的搜索。如果目錄名匹配則所有包含的內容都會被遞歸添加,目錄結構也會被保持
使用 /x 開關可以用來來排除文件或目錄
例:
將ProjectFiles目錄下的所有文件釋放到輸出目錄
SetOutPath "$INSTDIR" SetOverwrite ifnewer File /r "ProjectFiles\*.*" |
Delete
作用:從目標系統刪除文件
例:刪除文件
Delete "$SMPROGRAMS\Test.exe" |
Rename
作用:把源文件重命名為目標文件
例:
重命名文件
Rename $INSTDIR\file.ext $INSTDIR\file.dat |
CreateDirectory
作用:創建 (遞歸創建) 指定的目錄。當目錄不能創建時會放置一個錯誤標記。你也可以指定一個絕對路徑。
例:在默認Program Files目錄下創建一個Temp目錄
CreateDirectory "$SMPROGRAMS\Temp" |
RMDir
作用:刪除目錄
例:
刪除Resources及其子目錄
RMDir /r $INSTDIR\Resources |
SetOutPath
作用:設置輸出路徑($OUTDIR)且當路徑不存在時創建(需要時會遞歸創建)。必須為絕對路徑名,通常都使用 $INSTDIR。
例:
將用戶定義的解壓路徑作為輸出目錄
SetOutPath $INSTDIR |
CreateShortCut
作用:創建快捷文件.lnk 目標文件
例:
設置Test.exe的快捷方式Test.lnk,圖標為Test.ico。
CreateShortCut "$DESKTOP\Test.lnk" "$INSTDIR\Test.exe" "" "$INSTDIR\Resources\Picture\Icon\ Test.ico" |
注冊表操作
WriteRegStr、WriteRegExpandStr
作用:把字符串寫入注冊表。根鍵必須為下面列表之一:
HKCR 或 HKEY_CLASSES_ROOT
HKLM 或HKEY_LOCAL_MACHINE
HKCU 或HKEY_CURRENT_USER
HKU 或HKEY_USERS
HKCC 或HKEY_CURRENT_CONFIG
HKDD 或HKEY_DYN_DATA
HKPD 或HKEY_PERFORMANCE_DATA
SHCTX 或SHELL_CONTEXT
如果字串不能寫入注冊表則放置一個錯誤的標記。字串的類型為 REG_SZ 對應 WriteRegStr,或 REG_EXPAND_STR 對應 WriteRegExpandStr。如果注冊表鍵不存在則會自動創建。
例:
將程序信息寫入注冊表
Section -Post WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\Test.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\Test.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" SectionEnd |
ReadRegDWORD
作用:讀取注冊表信息
例:
在注冊表中讀取.net 版本
Function GetNetFrameworkVersion Push $1 Push $0 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" "Version" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5" "Version" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0\Setup" "InstallSuccess" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0\Setup" "Version" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Version" StrCmp $1 "" +1 +2 StrCpy $1 "2.0.50727.832" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v1.1.4322" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v1.1.4322" "Version" StrCmp $1 "" +1 +2 StrCpy $1 "1.1.4322.573" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\.NETFramework\policy\v1.0" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\.NETFramework\policy\v1.0" "Version" StrCmp $1 "" +1 +2 StrCpy $1 "1.0.3705.0" StrCmp $0 1 KnowNetFrameworkVersion +1 StrCpy $1 "not .NetFramework" KnowNetFrameworkVersion: Pop $0
Exch $1 FunctionEnd |
DeleteRegKey
作用:刪除一個注冊表鍵。如果指定了 /ifempty,則該注冊表鍵僅當它無子鍵時才會被刪除(否則,整個注冊表鍵將被刪除)。有效的根鍵值在后面的 WriteRegStr 列出。如果該鍵不能被刪除(或如果它不存在)則會放置一個錯誤的標記。
例:
清除注冊表信息
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" SetAutoClose true |
INI文件操作
ReadINIStr 用戶變量(輸出) INI文件 區段 項
作用:讀取INI文件。從 “INI文件” 的 “區段” 區段讀取 “項” 的值並把該值輸出到用戶變量。如果該項未找到時會放置一個錯誤標記且該用戶變量被賦為空值。
例:
讀取TimeZoneZh.ini文件中Field 1區段的State項,將值輸出到$0
ReadINIStr $0 "$PLUGINSDIR\TimeZoneZh.ini" "Field 1" "State" |
外部調用
ReserveFile
作用:把文件保存在稍后使用的數據區塊用於下面的調用。有時,預先打包文件,方便安裝加速釋放之用。
例:
ReserveFile "TimeZoneZh.ini" |
Exec
作用:這應該算是常用的命令了,執行一個指定的程序並且立即繼續安裝,就是直接執行一個程序。
例:
安裝Microsoft.NET.exe,程序不等待繼續執行下個步驟。
Exec '$INSTDIR\Microsoft.NET.exe |
ExecWait
作用:執行一個指定的程序並且等待運行處理結束。
例:
靜默安裝Microsoft.Net.exe安裝包,並等待安裝包運行結束。
ExecWait '$INSTDIR\Microsoft.NET.exe /quiet /norestart' $R1 |
RegDLL
作用:載入指定的 DLL 並且調用 DllRegisterServer (或入口點名稱,當指定之后)。當產生一個錯誤的時候會置一個錯誤標記(例如不能載入 DLL,不能初始化 OLE,不能找到入口點,或者函數返回任何其它錯誤 ERROR_SUCCESS (=0))。
其實就是注冊或加載你要的插件!
例:
注冊TIMProxy.dll插件
regdll “$instdir\TIMProxy.dll” |
UnRegDLL
作用:注銷DLL插件
例:
注銷TIMProxy.dll插件
unregdll “$instdir\TIMProxy.dll” |
!include
作用:包含頭文件
例:
引用"MUI.nsh"頭文件
!include "MUI.nsh" |
!insertmacro
作用:插入宏
例:
通過宏插入歡迎頁面
!insertmacro MUI_PAGE_WELCOME |
字符串操作
StrCpy
作用:復制字符串
StrCpy $0 "a bbbbbbbb" 就有$0 = "a bbbbbbbb"
StrCpy $0 "a bbbbbbbb" 3就有$0 = "a b"
StrCmp
作用:比較(不區分大小寫)“字串1”和“字串2”,如果兩者相等,跳轉到“相同時跳轉的標記”,否則跳轉到“不相同時跳轉的標記”。
邏輯操作
Push
作用:把一個字串壓入堆棧,該字串可隨后從堆棧里彈出。
Pop
作用:從堆棧里彈出一個字串到用戶變量 $x。如果堆棧是空的,則會置一個錯誤標記。
if
(1) IfAbort 退出時要跳轉的標記 [不是退出時要跳轉的標記]
如果調用退出時它將返回 true
(2) IfErrors 錯誤時跳轉的標記 [沒有錯誤時跳轉的標記]
檢測並清除錯誤標記,如果設了錯誤標記,則跳轉到“錯誤時跳轉的標記”,否則跳轉到“沒有錯誤時跳轉的標記”。
(3)IfFileExists 要檢測的文件 文件存在時跳轉的標記 [文件不存在時跳轉的標記]
檢測“要檢測的文件”是否存在(可以用通配符,或目錄),並當文件存在時跳轉到“文件存在時跳轉”,否則跳轉到“文件不存在時跳轉”。
Goto
作用:跳轉到指定標記。nsi腳本常常使用相對跳轉表示條件分枝,其語法是[+-][1-9],加號表示從當前位置往前跳轉,減號則表示從當前位置往后跳轉。數字表示跳轉的語句條數。
例:
按數字跳轉
Goto +4 ; 跳轉以下4條語句 Goto -3 ; 跳轉到前3條語句 |
例:
按標記跳轉
name "NSISDemo" outfile 'NSISDemo.exe' Section "NSISDemo" ReadRegStr $R0 HKLM SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Test "DisplayVersion" IntCmp $R0 "5.0" is5 lessthan5 morethan5 ;詳情查看 幫助4.9.4.13 IntCmp is5: DetailPrint "$R0 == 5.0" Goto int lessthan5: DetailPrint "$R0 < 5.0" Goto error2 morethan5: DetailPrint "$R0 > 5.0" Goto error1 int: MessageBox MB_OK "你系統中現有版本為$R0,點擊OK安裝更新" IDOK DetailPrint "安裝版本為: $R0" goto done error1: MessageBox MB_ICONSTOP|MB_OK "你系統中版本$R0高於更新版本" IDOK error2: MessageBox MB_ICONSTOP|MB_OK "你系統中版本$R0低於更新版本" IDOK done: SectionEnd |
MessageBox
作用:顯示一個包含“消息框文本”的消息框。“消息框選項列表”必須為下面的一個或多個,多個使用 | 來隔開。
MB_OK - 顯示 OK 按鈕
MB_OKCANCEL - 顯示 OK 和取消按鈕
MB_ABORTRETRYIGNORE - 顯示退出、重試、忽略按鈕
MB_RETRYCANCEL - 顯示重試和取消按鈕
MB_YESNO - 顯示是和否按鈕
MB_YESNOCANCEL - 顯示是、否、取消按鈕
MB_ICONEXCLAMATION - 顯示驚嘆號圖標
MB_ICONINFORMATION - 顯示信息圖標
MB_ICONQUESTION - 顯示問號圖標
MB_ICONSTOP - 顯示終止圖標
MB_TOPMOST - 使消息框在最前端顯示
MB_SETFOREGROUND - 設置前景
MB_RIGHT - 右對齊文本
MB_RTLREADING - RTL 閱讀次序
MB_DEFBUTTON1 - 默認為按鈕 1
MB_DEFBUTTON2 - 默認為按鈕 2
MB_DEFBUTTON3 - 默認為按鈕 3
MB_DEFBUTTON4 - 默認為按鈕 4
參考
官方論壇:http://forums.winamp.com/forumdisplay.php?s=&forumid=65
NSIS中文論壇:http://www.nsisfans.com/
輕狂志博客(NSIS大神):http://www.flighty.cn/html/bushu/index.html