以前一直用的是NSIS 2.x,但這些版本的NSIS打出來的安裝包沒有加聲明系統(tǒng)兼容性的manifest,也不好用軟件在打好的安裝包上加manifest,所以就換用了最新版本的NSIS 3.0。
換用3.0后之前正常的一些System::Call “xxx:xxx”函數(shù)失效了。
先懷疑NSIS 3.0的System插件有問題,換成2.x的System插件,也還是解決不了問題。并且未能找到System.dll的源碼。并且IDA反編譯之,也未發(fā)現(xiàn)兩者有什么關(guān)于加載庫的區(qū)別。
又懷疑是不是System語法問題,之前使用時(shí)直接沒有加各種參數(shù)原型說明,也沒有像文檔一樣使用參數(shù)列表和原型列表分開的調(diào)用方式。于是寫了個Hello.dll,里面定義了個簡單的Init函數(shù),以及另外一個和MessageBox函數(shù)格式相同的 MyMessageBox函數(shù)。
使用與調(diào)用 user32::MessageBox 相同的格式調(diào)用Hello:: MyMessageBox 依然未成功。
使用ApiMonitor監(jiān)控,發(fā)現(xiàn)LoadLibrary("hello")返回錯誤碼126,即“模塊未找到”。嘗試將hello分別放在與 安裝包同目錄,系統(tǒng)目錄,在環(huán)境變量PATH里的非系統(tǒng)目錄,結(jié)果只有放在系統(tǒng)目錄下才調(diào)用成功。
使用不同的系統(tǒng)來測試,win7、xp無此問題。win8與win10一樣有此問題。
使用c++編寫一個簡單的代碼測試來加載NSIS加載不了的dll,也是可以加載的
最后使用全路徑臨時(shí)解決此問題。
Function .onInit
StrCpy $InstallSuccess 0
Call CheckMutex
InitPluginsDir
SetOutPath $PLUGINSDIR
System::Call 'user32::MessageBox(p, t, t, i) i (0, "123", "System Example 2", ${MB_OKCANCEL})' "$7"
file "hello.dll"
System::Call 'hello::Init()' # 失敗
System::Call /NOUNLOAD 'hello::Init()' # 失敗
System::Call '$PLUGINSDIR\hello::MyMessageBox(p, t, t, i) i (0, "123", "System Example 2", ${MB_OKCANCEL})' "$7" #成功