NSIS安装脚本:编译时比对套件版本并更新头文件define变量咨询
现有代码问题说明
你当前的逻辑混淆了NSIS的编译期指令和运行期代码:System::Call、$R0变量、写在Section内的代码都是安装包运行时才会执行的逻辑,而!if、!define这类以!开头的指令是脚本编译阶段就会处理的指令,两者生命周期完全错开,现有写法无法实现编译时比对更新的需求。
正确实现方案
全程使用NSIS编译期指令完成目录读取、版本比对、头文件更新操作,示例代码如下:
!include "WordFunc.nsh" !include "StrFunc.nsh" ; 引入你现有的版本头文件,假设名为version.h !include "version.h" ; 编译期获取当前工作目录 !getcwdir CURR_COMPILE_DIR ; 提取目录最后一级作为套件版本名(格式如A1.2.3) ${WordFind} "${CURR_COMPILE_DIR}" "\" "-1" FULL_KIT_VERSION ; 若需要分离版本前缀和纯版本号,添加如下代码(按需开启) ; !substr PURE_VERSION "${FULL_KIT_VERSION}" 1 ; !if "${PURE_VERSION}" != "${APP_VERSION}" ; 版本比对 !if "${FULL_KIT_VERSION}" != "${APP_CLASSKIT}${APP_VERSION}" ; 遍历头文件替换APP_VERSION定义 !tempfile TMP_VERSION_FILE !fileopen SRC_HANDLE "version.h" r !fileopen TMP_HANDLE "${TMP_VERSION_FILE}" w !read_loop: !fileread ${SRC_HANDLE} CURR_LINE !if ${CURR_LINE} == eof !goto read_end !endif ; 匹配APP_VERSION定义行并替换 !if "${CURR_LINE}" =~ "!define APP_VERSION \"" ; 替换为提取到的正确版本,若用纯版本号则替换为${PURE_VERSION} !define CURR_LINE "!define APP_VERSION \"${FULL_KIT_VERSION}\"" !endif !filewrite ${TMP_HANDLE} "${CURR_LINE}$\n" !goto read_loop !read_end: !fileclose ${SRC_HANDLE} !fileclose ${TMP_HANDLE} ; 覆盖原头文件 !delfile "version.h" !copy /silent "${TMP_VERSION_FILE}" "version.h" !delfile "${TMP_VERSION_FILE}" ; 重新加载更新后的头文件,确保后续编译逻辑用最新版本号 !undef APP_VERSION !include "version.h" !endif
注意事项
- 上述代码需要放在脚本最开头,不要放在Section内,保证编译阶段优先执行
- 如果你的头文件路径不是当前目录,自行替换
version.h为实际的相对/绝对路径即可 - 正则匹配规则可根据你头文件中
!define APP_VERSION的实际书写格式调整,避免误替换
内容的提问来源于stack exchange,提问作者Jothi Prakash
相关产品推荐
相关产品推荐

