內置頁面的定制
”現代用戶界面“中提供了一些頁面,您可以通過插入宏的指令(如:!insertmacro MUI_PAGE_COMPONENTS)來把相應的頁面加入到安裝腳本,在安裝過程中,插入的頁面將按照先后順序出現,這些提供的安裝頁面如下:
MUI_PAGE_WELCOME
MUI_PAGE_LICENSE textfile
MUI_PAGE_COMPONENTS
MUI_PAGE_DIRECTORY
MUI_PAGE_STARTMENU pageid variable
MUI_PAGE_INSTFILES
MUI_PAGE_FINISH
通過NSIS用戶手冊我們知道每個內建的頁面都有三個回調函數。一個預置函數、一個顯示創建函數和一個離開函數。預置函數在頁面被創建之前被直接的調用,顯示函數在頁面被創建后且在顯示之前被直接調用,離開函數在用戶按下下一頁按鈕之后並且在頁面離開之前被直接調用。
類似的“現代用戶界面”,查看NSIS Modern User Interface的頁面自定義函數有以下三種類型,它們在插入頁面宏之前設置(!insertmacro MUI_PAGE_***):
MUI_PAGE_CUSTOMFUNCTION_PRE function ; 在其間你可以初始化變量或者決定下面插入的頁面是否要跳過
MUI_PAGE_CUSTOMFUNCTION_SHOW function ;在其間界面上所有控件的句柄都可以獲得,你可以自定義界面的任何部分
MUI_PAGE_CUSTOMFUNCTION_LEAVE function ;在其間可以校驗用戶的輸入
下面是一個例子,對區段變量進行設置(包括對區段組展開,區段設置成只讀、選中或不選),體現在組件界面中就是組件的只讀、選中或不選:
!define MUI_PAGE_CUSTOMFUNCTION_PRE ComponentsPre !insertmacro MUI_PAGE_COMPONENTS ; 組件頁面函數開始---------------------- Function ComponentsPre ; 設置區段選中並且只讀 IntOp $0 ${SF_SELECTED} | ${SF_RO} SectionSetFlags ${SEC01} $0 SectionSetFlags ${SEC02} $0 SectionSetFlags ${SEC03} $0 SectionSetFlags ${SEC04} $0 ; 如果選擇啟用Exchange功能則選中,否則不選 ${If} $IsEnableExchange == ${BST_CHECKED} SectionSetFlags ${SEC05} $0 ${Else} SectionSetFlags ${SEC05} ${SF_RO} ${EndIf} ; 如果選擇啟用Lync功能則選中,否則不選 ${If} $IsEnableLync == ${BST_CHECKED} SectionSetFlags ${SEC06} $0 ${Else} SectionSetFlags ${SEC06} ${SF_RO} ${EndIf} SectionSetFlags ${SEC07} $0 ; 設置區段組展開 IntOp $1 ${SF_SECGRP} | ${SF_EXPAND} IntOp $2 $1 | ${SF_RO} SectionSetFlags ${SECG01} $2 FunctionEnd ; 組件頁面函數結束----------------------
值得提一下的是指令(SectionSetFlags ${SEC01} $0)中變量${SEC01}是區段索引,定義了區段索引的新的區段如下所示:
Section "數據庫配置" SEC01 ; coding SectionEnd
自定義頁面
如果提供的這些內置頁面不能滿足您的需求,就需要您完全自定義頁面了,您的自定義頁面想出現在安裝過程中,和內置頁面一樣,需要按照安裝頁面的的順序插入頁面。插入自定義頁面的指令(參考NSIS用戶手冊,如:Page custom [創建函數] [離開函數] [標題] ),像我們這個實際應用中包含了10個頁面,我們按照安裝過程中頁面出現的順序插入頁面指令,如下代碼所示:
; 安裝程序頁面開始---------------------- ; 歡迎頁面 !insertmacro MUI_PAGE_WELCOME ; 許可頁面 !insertmacro MUI_PAGE_LICENSE "Licence.Txt" ; 系統環境檢查頁面 Page custom SystemEnvironmentCheckInit SystemEnvironmentCheckLeave ; 數據庫服務器配置頁面 ; Page custom DBServiceSettingsInit DBServiceSettingsLeave ; AD服務器配置頁面 Page custom ADServiceSettingsInit ADServiceSettingsLeave ; Exchange服務器配置頁面 Page custom ExchangeServiceSettingsInit ExchangeServiceSettingsLeave ; Lync服務器配置頁面 Page custom LyncServiceSettingsInit LyncServiceSettingsLeave ; 目錄選擇頁面 !insertmacro MUI_PAGE_DIRECTORY ; 組件頁面 !define MUI_PAGE_CUSTOMFUNCTION_PRE ComponentsPre !insertmacro MUI_PAGE_COMPONENTS ; 安裝記錄頁面 !insertmacro MUI_PAGE_INSTFILES ; 完成頁面 !insertmacro MUI_PAGE_FINISH ; 安裝程序頁面結束----------------------
下面我們以自定義頁面”Exchange服務器配置頁面“為例來說明怎么創建頁面(包含了一系列控件和相關布局),設置控件初始狀態、獲取控件的數據、校驗控件數據來控制下一步動作等。
這個頁面中有”是否啟用郵箱功能“選項,如果啟用郵箱,需要填寫Exchange版本、Exchange服務器地址、管理員賬戶和賬戶密碼等信息,默認是啟用郵箱狀態,Exchange版本默認是2013,切換”是否啟用郵箱功能“選項的狀態,會相應的改變郵箱設置的相關信息的可用/不可用狀態,如果啟用郵箱,信息輸入不全則點擊下一步時需要有類似”請輸入信息再進行下一步安裝“的提示,信息輸入校驗沒問題才進行下一步安裝。
根據插入的自定義頁面指令(Page custom ExchangeServiceSettingsInit ExchangeServiceSettingsLeave),我們知道這里有兩個基本的函數,一個是創建函數(ExchangeServiceSettingsInit),一個是離開函數(ExchangeServiceSettingsLeave)。結合需求在創建函數中我們可以創建頁面、創建並布局頁面上的控件、設置控件初始狀態、設置控件動作等,在離開函數中我們可以獲取控件數據、校驗數據、控制流程走向(是繼續下一步還是停止執行腳本)、保存數據等。
在這里我們創建頁面使用的是nsDialogs插件(可以參考nsDialogs和nsDialogs FAQ),需要包含插件頭文件指令(!include nsDialogs.nsh),對應的NSIS安裝目錄的Plugins文件夾(如:C:\Program Files (x86)\NSIS\Plugins)會有nsDialogs.dll文件。INI文件也可以用來創建自定義頁面,但因為INI既不靈活又不高效已經被nsDialogs取代啦。具體的創建頁面和控件的指令參考手冊說的很清楚了,不再累述。
現在重點說一下創建控件的布局,創建控件的一般指令:${NSD_Create*} x y width height text, 這里面關於控件的定位和大小有四個參數控制,X坐標、Y坐標、寬度和高度,取值可以有三種類型,一種是像素(就是我們通常的px)、一種是對話框單位(必須在數據后加后綴u)、再就是對話框大小的百分比(必須在數據后加后綴%),我這里的建議是使用百分比,這樣更好控制布局。
另外一個重點要說的是創建完控件后,會返回一個值放入堆棧中,這個值就是控件的句柄(即HWND),我們以后要設置或獲取控件的值等一切針對新創建控件的操作都需要句柄,所以我們需要從堆棧里彈出這個值保存在用戶變量中(如指令:Pop $TxtExchangeServerIP),設置控件初始值指令如:${NSD_SetText} $TxtExchangeServerIP “10.0.1.4”,獲取控件值如:${NSD_GetText} $TxtExchangeServerIP $ExchangeServerIP等。
針對控件的事件這里我們定義了一個單擊事件,如:${NSD_OnClick} $ChxEnableExchange EnableExchangeClick,單擊事件處理函數EnableExchangeClick中會根據“是否啟用郵箱功能”選項的值來設置其他控件的啟用/禁用狀態。涉及到選項(如:單選框、復選框)的狀態屬於兩個值中(選中${BST_CHECKED},未選中${BST_UNCHECKED})之一,設置控件的啟用/禁用狀態使用指令:SendMessage $TxtExchangeServerIP ${EM_SETREADONLY} 0 0/SendMessage $TxtExchangeServerIP ${EM_SETREADONLY} 1 0。
獲取文本框控件輸入的數據值時我們需要過去掉輸入字符串的前后空格和回車換行符等,我們可以自己寫一個處理字符串的方法並且宏定義后保存為Trim.nsh文件后使用,當然我們需要先引入頭文件(指令:!include Trim.nsh),使用例如:${Trim} $4 $0 第一個參數是處理后的字符串,第二個參數是源字符串。校驗輸入后我們可以把獲取的控件值保存在一個有意義的變量中供其他地方調用,如:StrCpy $ExchangeServerIP $4
下面是完整的創建”Exchange服務器配置頁面“的代碼,以供參考:
; Exchange服務器配置頁面函數開始---------------------- /*設置項:是否啟用郵箱功能、Exchange版本默認Exchange 2013、 Exchange服務器地址、管理員賬戶、賬戶密碼 */ Var ChxEnableExchange Var LabExchangeServerIP Var LabExchangeVersion Var LabExchangeUser Var LabExchangeUserPwd Var TxtExchangeServerIP Var TxtExchangeVersion Var TxtExchangeUser Var TxtExchangeUserPwd Function ExchangeServiceSettingsInit StrCpy $PAGE_TITLE "Exchange服務器配置" StrCpy $PAGE_SUBTITLE "當選擇啟用郵箱功能時,需要輸入以下內容(都為必填項):\ Exchange服務器地址、Exchange版本、管理員賬戶、賬戶密碼" !insertmacro MUI_HEADER_TEXT $PAGE_TITLE $PAGE_SUBTITLE nsDialogs::Create 1018 Pop $Dialog ${If} $Dialog == error Abort ${EndIf} ${NSD_CreateGroupBox} 0 0 100% 100% "設置項" Pop $GBox ${NSD_CreateCheckbox} 35% 5% 40% 20% "啟用Exchange相關功能" Pop $ChxEnableExchange ${NSD_CreateLabel} 10% 27% 20% 20% "服務器地址:" Pop $LabExchangeServerIP ${NSD_CreateLabel} 10% 42% 20% 20% "版本:" Pop $LabExchangeVersion ${NSD_CreateLabel} 10% 57% 20% 20% "管理員賬戶:" Pop $LabExchangeUser ${NSD_CreateLabel} 10% 72% 20% 20% "賬戶密碼:" Pop $LabExchangeUserPwd ${NSD_CreateText} 35% 27% 60% 10% "" Pop $TxtExchangeServerIP ${NSD_CreateText} 35% 42% 60% 10% "2013" Pop $TxtExchangeVersion ${NSD_CreateText} 35% 57% 60% 10% "" Pop $TxtExchangeUser ${NSD_CreatePassword} 35% 72% 60% 10% "" Pop $TxtExchangeUserPwd SendMessage $TxtExchangeVersion ${EM_SETREADONLY} 1 0 ${NSD_SetState} $ChxEnableExchange ${BST_CHECKED} ${NSD_GetState} $ChxEnableExchange $IsEnableExchange ${NSD_OnClick} $ChxEnableExchange EnableExchangeClick nsDialogs::Show FunctionEnd Function EnableExchangeClick ${NSD_GetState} $ChxEnableExchange $IsEnableExchange ${If} $IsEnableExchange == ${BST_CHECKED} SendMessage $TxtExchangeServerIP ${EM_SETREADONLY} 0 0 SendMessage $TxtExchangeUser ${EM_SETREADONLY} 0 0 SendMessage $TxtExchangeUserPwd ${EM_SETREADONLY} 0 0 ${Else} SendMessage $TxtExchangeServerIP ${EM_SETREADONLY} 1 0 SendMessage $TxtExchangeUser ${EM_SETREADONLY} 1 0 SendMessage $TxtExchangeUserPwd ${EM_SETREADONLY} 1 0 ${EndIf} FunctionEnd Function ExchangeServiceSettingsLeave ${If} $IsEnableExchange == ${BST_UNCHECKED} Return ${EndIf} ${NSD_GetText} $TxtExchangeServerIP $0 ${NSD_GetText} $TxtExchangeVersion $1 ${NSD_GetText} $TxtExchangeUser $2 ${NSD_GetText} $TxtExchangeUserPwd $3 ; ${Trim} $trimmedString $originalString ${Trim} $4 $0 ${Trim} $5 $1 ${Trim} $6 $2 ${Trim} $7 $3 ${If} $4 == "" ${OrIf} $5 == "" ${OrIf} $6 == "" ${OrIf} $7 == "" MessageBox MB_OK "請輸入信息再進行下一步安裝!" Abort ${EndIf} StrCpy $ExchangeServerIP $4 StrCpy $ExchangeVersion $5 StrCpy $ExchangeUser $6 StrCpy $ExchangeUserPwd $7 FunctionEnd ; Exchange服務器配置頁面函數結束----------------------
該自定義頁面執行效果截圖如下:
下面章節我們來介紹如何調用PowerShell命令。