執行外部程序
參考“ NSIS用戶手冊”,NSIS腳本語言中有三個指令可以執行外部程序:
- Exec:執行一個指定的程序並且立即繼續安裝。如:Exec '"$INSTDIR\command.exe" 參數'
- ExecShell:使用Windows的外殼關聯來執行一個指定的程序,並且立即繼續安裝。類似於我們在Windows目錄瀏覽窗口以默認打開方式來執行文件。如:ExecShell "open" "$INSTDIR\command.exe"
- ExecWait:執行一個指定的程序並且等待運行處理結束,再繼續安裝。如:ExecWait '"$INSTDIR\command.exe" 參數' $0($0當產生錯誤時設置為錯誤標記,未產生錯誤則為未指定)
以上命令當不能被運行時則會置一個錯誤標記,如果命令包含有空格,則要用引號把他們包括起來。
高級一點
如果我們的安裝程序需要執行一些后台命令,使用上面的指令時會出現命令行窗口,顯得很不和諧,我們就可以使用nsExec。具體的有三種用法:nsExec::Exec/ nsExec::ExecToLog/ nsExec::ExecToStack,不同的是nsExec::ExecToLog會把結果輸出到日志窗口, nsExec::ExecToStack會把結果輸出到堆棧中。
例如:nsExec::ExecToStack '"$INSTDIR\command.exe" 參數'
具體到我們需要執行PowerShell 命令文件,則 nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "${PSFile}" '
PowerShell封裝
NSIS網站上有有對PowerShell的支持,請參見PowerShell support,把其中的腳本保存為"psexec.nsh"文件,在需要使用的“*.nsi”文件中引用該頭文件(!include psexec.nsh)。
- Powershell命令調用例子
${PowerShellExec} "Get-WmiObject -Class Win32_ComputerSystem" Pop $R1 detailprint "PowerShell命令執行結果:$R1"
- Powershell文件調用例子
InitPluginsDir SetOutPath $PLUGINSDIR\Powershell File script.ps1 ${PowerShellExecFileLog} "$PLUGINSDIR\Powershell\script.ps1"
擴展能力
像上面介紹的"psexec.nsh"文件那樣頭文件能在一定程度上擴展NSIS腳本語言的功能,但遇到復雜的情況,更高級的就是使用插件來擴展它的功能。
插件可以使用其他編程語言來寫(如:C、C++等),里面有公開的函數,編譯后生成DLL文件,把DLL文件放在NSIS安裝目錄的Plugins文件夾下(如:C:\Program Files (x86)\NSIS\Plugins),NSIS腳本語言使用時通過dll::function“參數”進行調用(如:MSSQL_OLEDB::SQL_Execute "CREATE DATABASE [MyTestDB]")。當 NSIS 編譯器開始時它會掃描插件目錄的 DLL 文件並且列出找到的插件和輸出的函數,在編譯時如果遇到有序的冒號如 fred::flintstone編譯器將會作為關鍵字在該列表中查找,如果列表項列入了 fred.dll 並輸出 flintstone 則 NSIS 將會把 fred.dll 文件打包到安裝程序里。當插件命令執行時 NSIS 將會解壓所需的插件 DLL 文件到一個臨時目錄 ($PLUGINSDIR),把指定的參數全部壓入(從右到左次序),然后執行 DLL 函數。
如果你想調用一個用戶硬盤或其他地方里的插件,你可以使用CallInstDLL,從一個 NSIS 擴展動態鏈接庫里調用一個函數,需要自行把函數的參數全部壓入堆棧,擴展動態鏈接庫可以訪問堆棧和變量,如下例子:
Push "參數"
Push "另一個參數"
CallInstDLL $INSTDIR\somedll.dll somefunction
其中用C++寫的一個例子Contrib/ExDLL可以參考。另外NSIS網站提供了一些插件,請參見Category:Plugins ,這里面包括我們接下章節要講解的訪問數據庫的插件。