如何在NSIS中记录所选安装选项及已安装文件?含bat替代方案
问题解答
一、NSIS内部直接实现(推荐)
完全可以在NSIS脚本里搞定日志记录,不用依赖外部工具,具体操作如下:
1. 生成时间戳
NSIS自带GetDateTimeString命令能直接生成时间戳,比如生成YYYY-MM-DD HH:MM:SS格式的代码:
; 把时间戳存到变量$0里 StrCpy $0 "" GetDateTimeString $0 "%Y-%m-%d %H:%M:%S"
2. 遍历Section记录选中状态
用SectionGetFlags命令检查每个Section的选中状态(通过${SF_SELECTED}标记判断),再把选中的选项和时间戳写入日志文件。示例代码:
; 日志文件存到安装目录下的install_log.txt StrCpy $1 "$INSTDIR\install_log.txt" ; 先写个时间戳开头 FileOpen $2 $1 a FileWrite $2 "=== 安装选项记录 $0 ===$\r$\n" FileClose $2 ; 先定义几个示例Section,实际按你自己的需求写 Section "主程序" SEC_MAIN SectionEnd Section "插件A" SEC_PLUGINA SectionEnd Section "插件B" SEC_PLUGINB SectionEnd ; 在安装成功的回调里执行日志记录 Function .onInstSuccess ; 重新获取一次当前时间戳 StrCpy $0 "" GetDateTimeString $0 "%Y-%m-%d %H:%M:%S" StrCpy $1 "$INSTDIR\install_log.txt" FileOpen $2 $1 a FileWrite $2 "安装完成时间: $0$\r$\n" FileWrite $2 "选中的安装项:$\r$\n" ; 检查主程序是否被选中 SectionGetFlags ${SEC_MAIN} $3 IntOp $3 $3 & ${SF_SELECTED} ${If} $3 != 0 FileWrite $2 "- 主程序$\r$\n" ${EndIf} ; 检查插件A SectionGetFlags ${SEC_PLUGINA} $3 IntOp $3 $3 & ${SF_SELECTED} ${If} $3 != 0 FileWrite $2 "- 插件A$\r$\n" ${EndIf} ; 检查插件B SectionGetFlags ${SEC_PLUGINB} $3 IntOp $3 $3 & ${SF_SELECTED} ${If} $3 != 0 FileWrite $2 "- 插件B$\r$\n" ${EndIf} FileWrite $2 "=========================$\r$\n$\r$\n" FileClose $2 FunctionEnd
3. 记录已安装文件(可选)
如果要记录具体安装的文件,在每个Section复制文件后,直接把文件名追加到日志里就行:
Section "插件A" SEC_PLUGINA SetOutPath "$INSTDIR\Plugins" File "Plugins\A.dll" ; 记录这个文件的安装路径 StrCpy $1 "$INSTDIR\install_log.txt" FileOpen $2 $1 a FileWrite $2 "已安装文件: $INSTDIR\Plugins\A.dll$\r$\n" FileClose $2 SectionEnd
二、外部脚本(如BAT)实现
要是你非得用外部工具,也可以让NSIS调用BAT脚本传递参数,但不如内部实现简洁:
1. 写个BAT脚本(install_log.bat)
@echo off set timestamp=%date% %time% set logfile=%1 echo === 安装选项记录 %timestamp% === >> "%logfile%" echo 选中的安装项: >> "%logfile%" :loop shift if "%~1"=="" goto end echo - %~1 >> "%logfile%" goto loop :end echo ========================= >> "%logfile%" echo. >> "%logfile%"
2. 在NSIS里调用BAT
安装完成时,先收集选中的Section名称,再作为参数传给BAT:
Function .onInstSuccess StrCpy $1 "$INSTDIR\install_log.txt" StrCpy $2 "" ; 收集选中的选项名称 SectionGetFlags ${SEC_MAIN} $3 IntOp $3 $3 & ${SF_SELECTED} ${If} $3 != 0 StrCat $2 "主程序 " ${EndIf} SectionGetFlags ${SEC_PLUGINA} $3 IntOp $3 $3 & ${SF_SELECTED} ${If} $3 != 0 StrCat $2 "插件A " ${EndIf} ; 调用BAT脚本,传递日志路径和选中的选项 ExecWait '"$INSTDIR\install_log.bat" "$1" $2' FunctionEnd
总结
优先用NSIS内部实现,不用额外带文件,逻辑也更可控;外部BAT方式适合已有现成脚本或者需要复杂日志处理的场景,但得多带一个BAT文件,维护起来麻烦点。
内容的提问来源于stack exchange,提问作者Tyler
相关产品推荐
相关产品推荐

