NSIS 3.0 System Call 失败问题

以前一直用的是NSIS 2.x,但这些版本的NSIS打出来的安装包没有加声明系统兼容性的manifest,也不好用软件在打好的安装包上加manifest,所以就换用了最新版本的NSIS 3.0。

换用3.0后之前正常的一些System::Call “xxx:xxx”函数失效了。

  • 先怀疑NSIS 3.0的System插件有问题,换成2.x的System插件,也还是解决不了问题。并且未能找到System.dll的源码。并且IDA反编译之,也未发现两者有什么关于加载库的区别。
  • 又怀疑是不是System语法问题,之前使用时直接没有加各种参数原型说明,也没有像文档一样使用参数列表和原型列表分开的调用方式。于是写了个Hello.dll,里面定义了个简单的Init函数,以及另外一个和MessageBox函数格式相同的 MyMessageBox函数。

  • 使用与调用 user32::MessageBox 相同的格式调用Hello:: MyMessageBox 依然未成功。

  • 使用ApiMonitor监控,发现LoadLibrary(“hello”)返回错误码126,即“模块未找到”。尝试将hello分别放在与 安装包同目录,系统目录,在环境变量PATH里的非系统目录,结果只有放在系统目录下才调用成功。

  • 使用不同的系统来测试,win7、xp无此问题。win8与win10一样有此问题。

  • 使用c++编写一个简单的代码测试来加载NSIS加载不了的dll,也是可以加载的

最后使用全路径临时解决此问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
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" #成功