NSIS技术问询:如何通过循环读取.dat文件实现文件复制?
NSIS读取.dat文件时变量解析异常问题解决
嘿,我明白你碰到的麻烦了!先理下你的场景:
你把需要复制的文件列表存进了CopyFileList.dat,内容是:
\Bin\a.exe \Bin\b.dll \Bin\c.dll \Bin\d.dll \Bin\e.dll \Bin\f.dll
然后写了这段NSIS代码想逐行读取并复制文件:
ClearErrors FileOpen $0 "CopyFileList.dat" r loop: FileRead $0 $1 Strcmp $1 "" done StrCpy $varBinFileName $1 File /r "${TARGETDIR}\$varBinFileName" goto loop done: FileClose $0
结果运行后发现,程序居然把$varBinFileName当成了字面量路径,而不是去读取这个变量里存的文件路径——这问题出在NSIS的指令执行时机上!
问题根源
File是编译时指令,意思是它在脚本编译阶段就会解析里面的字符串,而不是等到程序运行时再去读取变量的值。所以你写${TARGETDIR}\$varBinFileName时,编译阶段它只会把$varBinFileName当成普通文本,根本不会去解析这个运行时变量。
解决办法
要处理运行时动态读取的路径,得用运行时的复制函数,而不是编译时的File指令。这里给你两种可行的方案:
方案1:使用NSIS的FileFunc插件(推荐)
先确保你导入了FileFunc.nsh插件,然后修改代码如下:
!include "FileFunc.nsh" ClearErrors FileOpen $0 "CopyFileList.dat" r loop: FileRead $0 $1 Strcmp $1 "" done ; 关键:去掉FileRead读进来的换行符,不然路径会无效 StrTrim $1 $1 ; 拼接完整源路径 StrCpy $2 "${TARGETDIR}$1" ; 调用运行时的复制函数,第二个参数是目标目录 FileCopy $2 "${YOUR_TARGET_FOLDER}\" goto loop done: FileClose $0
把${YOUR_TARGET_FOLDER}替换成你实际要复制到的目录就行。
方案2:调用系统xcopy命令
如果不想用插件,也可以直接调用系统的xcopy命令,用ExecWait执行:
ClearErrors FileOpen $0 "CopyFileList.dat" r loop: FileRead $0 $1 Strcmp $1 "" done StrTrim $1 $1 StrCpy $2 "${TARGETDIR}$1" ; 调用xcopy,/Y是覆盖不提示,/E是复制子目录 ExecWait 'xcopy "$2" "${YOUR_TARGET_FOLDER}\" /Y /E' goto loop done: FileClose $0
额外提醒
FileRead会把每行末尾的换行符也读进变量里,所以一定要用StrTrim去掉这些多余的空白字符,不然拼接出来的路径会无效,导致找不到文件。
内容的提问来源于stack exchange,提问作者areum
相关产品推荐
相关产品推荐

