【问题标题】:Batch File modify text file for NSIS installer批处理文件修改 NSIS 安装程序的文本文件
【发布时间】:2012-03-25 20:16:10
【问题描述】:

作为 NSIS 脚本生成器的一部分,我有一个文件名列表,这些文件名当前位于名为 files.txt 的文件中。内容示例如下...

c:\myfolder\assets\startup.xml
c:\myfolder\assets\begin.exe
c:\myfolder\assets\begin.swf
c:\myfolder\assets\resources\assets\text\help.pdf
c:\myfolder\assets\resources\assets\text\license.rtf
c:\myfolder\assets\resources\assets\swf\piano.swf
c:\myfolder\assets\resources\assets\swf\numbers.swf
c:\myfolder\assets\resources\section1\resource1\item1.jpg
c:\myfolder\assets\resources\section1\resource1\item2.jpg
c:\myfolder\assets\resources\section4\resource1\item7.jpg
c:\myfolder\assets\resources\section4\resource1\item8.jpg

我正在尝试使用批处理文件处理此文件列表,以便它们最终看起来像这样......

SetOutPath "$INSTDIR"
File "c:\myfolder\assets\startup.xml"
SetOutPath "$INSTDIR"
File "c:\myfolder\assets\begin.exe"
SetOutPath "$INSTDIR"
File "c:\myfolder\assets\begin.swf"
SetOutPath "$INSTDIR\resources\assets\text"
File "c:\myfolder\assets\resources\assets\text\help.pdf"
SetOutPath "$INSTDIR\resources\assets\text"
File "c:\myfolder\assets\resources\assets\text\license.rtf"
SetOutPath "$INSTDIR\resources\assets\swf"
File "c:\myfolder\assets\resources\assets\swf\piano.swf"
SetOutPath "$INSTDIR\resources\assets\swf"
File "c:\myfolder\assets\resources\assets\swf\numbers.swf"
SetOutPath "$INSTDIR\resources\section1\resource1"
File "c:\myfolder\assets\resources\section1\resource1\item1.jpg"
SetOutPath "$INSTDIR\resources\section1\resource1"
File "c:\myfolder\assets\resources\section1\resource1\item2.jpg"
SetOutPath "$INSTDIR\resources\section4\resource1"
File "c:\myfolder\assets\resources\section4\resource1\item7.jpg"
SetOutPath "$INSTDIR\resources\section4\resource1"
File "c:\myfolder\assets\resources\section4\resource1\item8.jpg"

我尝试了一些方法,但还没有真正找到解决方案。谁能指出我正确的方向?

更新

好的,从 Aacini 的帖子开始,我已经稍微修改了批处理文件,如下所示...

dir "c:\n\assets" /b /s > "c:\n\original.txt"
type "c:\n\original.txt" | findstr \. > "c:\n\filelist.txt"
@echo off
setlocal EnableDelayedExpansion
SET PATH=C:\n
set INSTDIR="c:\n\assets\"
( for /F "delims=" %%a in (filelist.txt) do (
     set "filePath=%%~DPa"
     set "outPath=!filePath:%INSTDIR%=!"
     if defined outPath set "outPath=\!outPath:~0,-1!"
     echo SetOutPath "$INSTDIR!outPath!"
     echo File "%%a"
  )
) > "c:\n\result.txt"
REM move /Y c:\result.txt files.txt

我主要使用引号进行了一些更改以允许在路径名称中使用空格,并且我还设置了路径以允许从 NSIS 调用时一切正常工作。我现在面临的问题是,而不是......

SetOutPath "$INSTDIR\assets"
File "c:\my folder\assets\startup.xml"

我明白了……

SetOutPath "$INSTDIR\c:\my folder\assets"
File "c:\my folder\assets\startup.xml"

我认为这是一个非常容易解决的问题,但我正在努力改变它!我做错了什么?

【问题讨论】:

    标签: batch-file nsis


    【解决方案1】:

    NSIS 可以包含一个带有File /r "c:\myfolder\" 等的目录树,但如果你真的想解析一个文本文件,你可以尝试这样的事情:

    ;create a file list for this example
    !delfile "$%temp%\testfilelist.txt"
    !appendfile "$%temp%\testfilelist.txt" c:\myfolder\assets\begin.swf$\n
    !appendfile "$%temp%\testfilelist.txt" c:\myfolder\assets\resources\assets\text\help.pdf$\n
    !appendfile "$%temp%\testfilelist.txt" c:\myfolder\assets\resources\assets\text\license.rtf$\n
    !appendfile "$%temp%\testfilelist.txt" c:\myfolder\assets\resources\assets\swf\piano.swf$\n
    !appendfile "$%temp%\testfilelist.txt" c:\myfolder\assets\resources\assets\swf\numbers.swf$\n
    !appendfile "$%temp%\testfilelist.txt" c:\myfolder\assets\resources\section1\resource1\item1.jpg$\n
    !appendfile "$%temp%\testfilelist.txt" c:\myfolder\assets\resources\section1\resource1\item2.jpg$\n
    
    outfile "$%temp%\test.exe"
    section
    !define srcroot "c:\myfolder\assets" ;batch file needs to generate a relative path for $instdir
    !define filelist "$%temp%\testfilelist.txt"
    !tempfile BATCH
    !tempfile NSH
    !appendfile "${BATCH}.cmd" '@echo off&setlocal&goto main$\n'
    !appendfile "${BATCH}.cmd" ':StrLen$\n'
    !appendfile "${BATCH}.cmd" 'set #=%~2%&set length=0$\n'
    !appendfile "${BATCH}.cmd" ':stringLengthLoop$\n'
    !appendfile "${BATCH}.cmd" 'if defined # (set #=%#:~1%&set /A length += 1&goto stringLengthLoop)$\n'
    !appendfile "${BATCH}.cmd" 'set "%~1=%length%"&GOTO :EOF$\n'
    !appendfile "${BATCH}.cmd" ':writ$\n'
    !appendfile "${BATCH}.cmd" 'setlocal&set "d=%~2"$\n'
    !appendfile "${BATCH}.cmd" 'setlocal enabledelayedexpansion$\n'
    !appendfile "${BATCH}.cmd" 'echo SetOutPath "$INSTDIR!d:~%rlen%!" >>"%~3"$\n'
    !appendfile "${BATCH}.cmd" 'echo File "%~1" >>"%~3"$\n'
    !appendfile "${BATCH}.cmd" 'endlocal&endlocal&GOTO :EOF$\n'
    !appendfile "${BATCH}.cmd" ':main$\n'
    !appendfile "${BATCH}.cmd" 'call :StrLen rlen "%~2"$\n'
    !appendfile "${BATCH}.cmd" 'for /F "usebackq tokens=*" %%A in ("%~1") do call :writ "%%~A" "%%~dpA" "%~3"$\n'
    !system '"${BATCH}.cmd" "${filelist}" "${srcroot}" "${NSH}"' = 0
    !delfile "${BATCH}.cmd"
    !delfile "${BATCH}"
    !undef BATCH
    !include "${NSH}"
    !delfile "${NSH}"
    !undef NSH
    sectionend
    

    【讨论】:

    • 这对我的例子来说没问题,但我希望这个过程随着文件列表的变化而自动进行。我意识到我可以直接从 NSIS 生成文件列表,但在我的情况下使用文本文件中的文件更容易。
    • @fightstarr20:这怎么不是自动的? (srcroot部分除外)
    • 当然 !appendfile "$%temp%\testfilelist.txt" c:\myfolder\assets\begin.swf$\n 行必须针对我需要的每组新文件进行更改添加?
    • 我错了,我的批处理文件中生成文件列表的部分漏掉了,对不起!
    • 真正的脚本中不存在 !appendfile "$%temp%\testfilelist.txt" 行,如果不清楚,请见谅...
    【解决方案2】:

    这个批处理文件做你需要的:

    @echo off
    setlocal EnableDelayedExpansion
    set INSTDIR=c:\myfolder\assets\
    ( for /F "delims=" %%a in (files.txt) do (
         set "filePath=%%~DPa"
         set "outPath=!filePath:%INSTDIR%=!"
         if defined outPath set "outPath=\!outPath:~0,-1!"
         echo SetOutPath "$INSTDIR!outPath!"
         echo File "%%a"
      )
    ) > result.txt
    REM move /Y result.txt files.txt
    

    首先测试它并检查result.txt文件。如果一切正常,删除最后一个命令中的 REM 部分。

    【讨论】:

    • 如果我直接运行这个批处理文件对我来说很好,但是尝试使用 Excec 从 NSIS 启动它却无法生成 result.txt 文件
    【解决方案3】:

    我稍微修改了你的批次:

    dir "c:\n\assets" /b /s > "c:\n\original.txt"
    FOR /F "tokens=3,4 delims=\" %%G IN (original.txt) DO @echo %%G\%%H| tee -a filelist.txt
    @echo off
    setlocal EnableDelayedExpansion
    SET PATH=C:\n\
    set INSTDIR=C:\n\assets\
    ( for /F "delims=" %%a in (filelist.txt) do (
         set "filePath=%%~DPa"
         set "outPath=!filePath:%INSTDIR%=!"
         if defined outPath set "outPath=\!outPath:~0,-1!"
         echo SetOutPath "$INSTDIR\%%a"
         echo File "!Path!%%a"
      )
    ) > "c:\n\result.txt"
    REM move /Y c:\result.txt files.txt
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-16
      • 2016-12-12
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 2013-06-22
      • 1970-01-01
      相关资源
      最近更新 更多