NSIS ExecDos插件在≥3.07版本makensis.exe中无法正常工作
故障原因
NSIS 3.07及以上版本的makensis.exe调整了插件调用栈的内存布局规则,同时移除了对未适配新版SDK的老旧第三方插件的隐式兼容。
官方原版ExecDos插件最后一次更新早于NSIS 3.07发布,基于旧版NSIS插件SDK编译,内部硬编码了旧版栈偏移地址用于读取入参、写入返回值。在新版编译器环境下调用ExecDos:exec时,插件会读取到错误的内存地址,直接触发内存访问异常,因此会出现命令立即返回、返回值为异常错误码的现象。如果使用Unicode模式的新版makensis,未做Unicode适配的老版ANSI格式ExecDos插件还会直接加载失败。
修复方案
可根据实际需求选择以下任意一种方案:
- 替换适配新版的重编译插件:获取基于NSIS 3.07+新版SDK重新编译的ExecDos插件文件,替换NSIS安装路径下
Plugins目录内的旧版ExecDos.dll即可,注意所选插件版本要和当前使用的makensis编码模式(ANSI/Unicode)匹配。 - 改用官方内置插件替代(推荐):新版NSIS自带的
nsExec插件已完全覆盖ExecDos的核心能力,包括执行命令行程序、等待进程退出、捕获输出内容、获取退出码,无兼容性问题。
代码替换示例:
原ExecDos调用写法:
等价nsExec写法:ExecDos::exec '"$INSTDIR\your_tool.exe" /run' "$INSTDIR\run.log" Pop $0 ; 读取执行返回值
如果不需要将输出写入文件、直接打印到安装日志,使用nsExec::ExecToFile "$INSTDIR\run.log" '"$INSTDIR\your_tool.exe" /run' Pop $0 ; 同样可读取程序退出码/执行错误码nsExec::ExecToLog命令即可。 - 临时兼容方案(不推荐):如果必须使用原版老旧ExecDos插件,可将
makensis.exe降级到3.06及更早版本,但旧版编译器存在已知安全漏洞,不建议用于正式发布的安装包。
内容的提问来源于stack exchange,提问作者Ilyan
相关产品推荐
相关产品推荐

