某些安裝程序需要調用包含於第三方開發的 DLL 中的函數。最佳的例子就是安裝一個 Palm(TM) 通道。
一些關於 System.dll 的背景資料
System.dll 插件 (由 Brainsucker 開發) 使你可以通過提供 Call 函數來調用外部 DLL。有大量的由 System.dll 提供的函數,但是它們並不適合放在這裡。若要得到更多關於其它函數的詳細訊息,請鎖上門,取下電話,System 說明文件,並閱讀。
資料類型
System.dll 可以識別一下資料類型
:
將 System.dll 變量映射為 NSIS 裡的內置變量
如果你不需要返回任何資料,那麼這裡沒有什麼可以用來調用一個外部函數的指向。System.dll 可以通過以下方式將函數變量映射為 NSIS 腳本變量:
NSIS $0..$9 可與 System.dll r0..r9 相對應;NSIS $R0..$R9 也可與 System.dll r10..r19 相對應
每個參數由類型,輸入和輸出指定。可以用一個點跳過輸入或輸出。例如:
字元串 (一個字元數組的指針),輸入為 '輕鬆調用' :
t '輕鬆調用'
字元串 (一個字元數組的指針), 輸入從 $5 取值,並且經轉換為由調用產生的數組後,最後儲存到 $R8 :
t r5R8
一個整數指針,從 $1 取值並放入 $2 :
*i r1r2
一個 64-bit 整數指針,輸出送入堆棧,沒有輸入 :
*l .s
通過 System.dll::Call 調用第三方 DLL 中的一個函數,Call 的用法如下 :
System::Call 'YourDllName::YourDllFunction(i, *i, t) i(r0, .r1, r2) .r3'
後面的的 (r0, .r1, r2) .r3 段是用來傳送 DLL 和 NSIS 腳本之間的參數。就像在這個參數列表中看到的一樣,類型和輸入、輸出是可以分開的。每個 "(參數列表) 返回值" 塊不用考慮和/或新增上一個。在這裡,第一塊指定類型而第二塊指定輸入和輸出。
開始編輯 NSIS 腳本之前
在開始編輯 NSIS 代碼之前,首先需要瞭解要調用函數的原型。在這個例子裡,我們使用 Palm 'CondMgr.dll' 中的'CmGetHotSyncExecPath' 函數。這個函數用來返回 'HotSync.exe' 的完整路徑。
函數定義
int CmGetHotSyncExecPath(TCHAR *pPath, int *piSize);
參數
返回值:
同樣的,如果 buffer 太小,*int 中的值為緩衝應當的大小 (TCHAR 類型)。
上面的函數的定義轉換到 System.dll 定義:
CmGetHotSyncExecPath(t, *i) i
也就是,它有一個文字變量,一個整數指針,並返回一個整數值。
使用外部 DLL 函數
在選出了函數所要做的事情,以及它是如何轉換到 System.dll 格式之後,就可以在 NSIS 腳本中使用這個函數了。
首先,推薦在需要多次調用 System.dll 時,禁止插件卸載。 根據 Brainsucker (以及其他人) 的說法,這樣可以提高安裝包的執行速度 (減少了卸載 - 重新裝載的時間)。
其次,你必須將輸出目錄更改為你要用的 DLL 所在的目錄。如果 DLL 在系統路徑中,那麼它也能工作,但並沒有經過測試。
下面的代碼段會將 condmgr.dll 釋放到一個臨時目錄中,然後執行 CmGetHotSyncExecPath 函數,顯示返回的資料並最終卸載 System.dll 插件。
; **** snip **** SetPluginUnload alwaysoff Function loadDll SetOutPath $TEMP\eInspect ; 建立臨時目錄 File bin\CondMgr.dll ; 釋放 DLL StrCpy $1 ${NSIS_MAX_STRLEN} ; assign memory to $0 System::Call 'CondMgr::CmGetHotSyncExecPath(t, *i) i(.r0, r1r1).r2' DetailPrint '路徑: "$0"' DetailPrint "路徑長度: $1" DetailPrint "返回值: $2" ; 最後一次插件調用必須沒有 /NOUNLOAD 參數,否則 NSIS 將不能在安裝結束後刪除 ; 臨時的 DLL 檔案 SetPluginUnload manual ; 什麼都不作 (目的就是為了卸載 System.dll) System::Free 0 FunctionEnd ; **** snip ****
這個函數將在觀看詳細訊息頁面產生下面的輸出:
輸出目錄: c:\windows\TEMP\eInspect
解壓: CondMgr.dll
路徑: "C:\Dave\palm\Hotsync.exe"
路徑長度: 24
返回值: 0
Written by djc
感謝
在此感謝 kichik 和 Sunjammer 花費了大量時間解決這些問題。同時感謝 brainsucker 首先做了這個 System.dll 插件。祝你好運!