当前位置: 首页 > 文档资料 > NSIS 用户手册 >

E.2 文本函数头文件

优质
小牛编辑
134浏览
2023-12-01

E.2.1 介绍

包含头文件:

!include "TextFunc.nsh"

包含函数 "LineRead" 用于安装和 "TrimNewLines" 用于卸载:

!insertmacro LineRead
!insertmacro un.TrimNewLines

调用函数:

Section Install
    ${LineRead} "C:\a.log" "-1" $R0
    ; $R0="Last line$\r$\n"
SectionEnd
Section un.Install
    ${un.TrimNewLines} "最后一行$\r$\n" $R0
    ; $R0="Last line"
SectionEnd

E.2.2 LineFind

  • 查找文本文件中的指定行并在回调函数中编辑或者查看该行

语法:

${LineFind} "[File1]" "[File2|/NUL]" "[LineNumbers]" "Function"
"[File1]"         ; 输入文本文件
                  ;
"[File2|/NUL]"    ; [File2]
                  ;   输出文本文件
                  ;   如果为空则 File2=File1
                  ; [/NUL]
                  ;   不输出文本文件 (仅读取 File1)
                  ;
"[LineNumbers]"   ; [No|-No|No:No|{No}|{-No}|{No:No}]
                  ;   1:-1     更改所有行 (默认)
                  ;   2        从开头起第 2 行
                  ;   -3       从末尾起第 3 行
                  ;   5:9      从第 5 行到第 9 行范围
                  ;   {2}      仅输出从开头起第 2 行
                  ;   {-3}     仅输出从末尾起第 3 行
                  ;   {5:9}    仅输出从第 5 行到第 9 行范围
                  ;
"Function"        ; 指定行的回调函数
Function "Function"
    ; $R9       当前行
    ; $R8       当前行号
    ; $R7       当前负行号
    ; $R6       当前行范围
    ; $R5       要读取的文件句柄
    ; $R4       要写入的文件句柄 ($R4="" 如果指定 "/NUL")
    ; 你可以使用任何字符串函数
    ; $R0-$R3 未使用,可用于保存数据
    ; ...
    Push $var      ; 如果 $var="StopLineFind"  则退出函数
                   ; 如果 $var="SkipWrite"     则跳过当前行 (如果指定 "/NUL" 则忽略)
FunctionEnd

注意:
- 输入文件时的错误标记
- 输出文件路径不存在时的错误标记
- 必须指定为增长的范围 (2 4:5 9:-8 -5:-4 -2:-1)
- 如果没有更改,输出文件将不会更新

示例1 (删除前两个符号):

Section
    ${LineFind} "C:\a.log" "C:\a-edited.log" "3:-1" "Example1"
    IfErrors 0 +2
    MessageBox MB_OK "错误!"
SectionEnd
Function Example1
    ${TrimNewLines} '$R9' $R9
    StrCpy $R9 $R9 '' 2
    StrCpy $R9 '$R9$\r$\n'
    ;从第三行开始并删除前两个符号
    Push $0
FunctionEnd

示例2 (显示更改的行):

Section
    ${LineFind} "C:\a.log" "a.log" "{5:12 15 -6:-5 -1}" "Example2"
    IfErrors 0 +2
    MessageBox MB_OK "错误!"
SectionEnd
Function Example2
    ${TrimNewLines} '$R9' $R9
    StrCpy $R9 "$R9   ~已更改行 ($R8)~$\r$\n"
    Push $0
FunctionEnd

示例3 (删除行):

Section
    ${LineFind} "C:\a.log" "\logs\a.log" "2:3 10:-5 -3:-2" "Example3"
    IfErrors 0 +2
    MessageBox MB_OK "错误!"
SectionEnd
Function Example3
    StrCpy $0 SkipWrite
    Push $0
FunctionEnd

示例4 (插入行):

Section
    ${LineFind} "C:\a.log" "" "10" "Example4"
    IfErrors 0 +2
    MessageBox MB_OK "错误!"
SectionEnd
Function Example4
    FileWrite $R4 "---第一行---$\r$\n"
    FileWrite $R4 "---第二行...---$\r$\n"
    Push $0
FunctionEnd

示例5 (带更改行数的文件内容替换 - 需要 "WordFunc.nsh"):

!include "WordFunc.nsh"
!insertmacro WordReplace
Section
    StrCpy $R0 0
    ${LineFind} "C:\a.log" "C:\logs\a.log" "1:-1" "Example5"
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK +2
    MessageBox MB_OK "已更改行数=$R0"
SectionEnd
Function Example5
    StrCpy $1 $R9
    ${WordReplace} '$R9' ' ' '_' '+*' $R9
    StrCmp $1 $R9 +2
    IntOp $R0 $R0 + 1
    ;$R0   已更改行数
    Push $0
FunctionEnd

示例6 (要裁剪或删除的行字符串):

Section
    ${LineFind} "\a.log" "C:\logs\a.log" "" "Example6"
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK +2
    MessageBox MB_OK "已处理行数=$R1:$R2"
SectionEnd
Function Example6
    ;(裁剪从一行到另外一行的几行 (也包括那一行))
    StrCmp $R0 finish stop
    StrCmp $R0 start finish
    StrCmp $R9 '开始行$\r$\n' 0 skip
    StrCpy $R0 start
    StrCpy $R1 $R8
    goto code
    finish:
    StrCmp $R9 '完成行$\r$\n' 0 code
    StrCpy $R0 finish
    StrCpy $R2 $R8
    goto code
    skip:
    StrCpy $0 SkipWrite
    goto output
    stop:
    StrCpy $0 StopLineFind
    goto output
    ;;(删除从一行到另外一行的几行 (也包括那一行))
    ; StrCmp $R0 finish code
    ; StrCmp $R0 start finish
    ; StrCmp $R9 '开始行$\r$\n' 0 code
    ; StrCpy $R0 start
    ; StrCpy $R1 $R8
    ; goto skip
    ; finish:
    ; StrCmp $R9 '完成行$\r$\n' 0 skip
    ; StrCpy $R0 finish
    ; StrCpy $R2 $R8
    ; skip:
    ; StrCpy $0 SkipWrite
    ; goto output
    code:
    ;...
    output:
    Push $0
FunctionEnd

示例7 (读取行):

Section
    ${LineFind} "C:\a.log" "/NUL" "1:-1" "Example7"
    IfErrors 0 +2
    MessageBox MB_OK "错误!"
SectionEnd
Function Example7
    MessageBox MB_OKCANCEL '$$R9  "Line"=[$R9]$\n$$R8     "#" =[$R8]' IDOK +2
    StrCpy $0 StopLineFind
    Push $0
FunctionEnd

E.2.3 LineRead

  • 获取文件中指定行号的内容

语法:

${LineRead} "[File]" "[LineNumber]" $var
"[File]"         ; 输入文本文件
                 ;
"[LineNumber]"   ; [No|-No]
                 ;   3    从开头起行号
                 ;   -5   从结尾起行号
                 ;
$var             ; 结果:行内容

注意:
- 输入文件时的错误标记
- 行号未找到时的错误标记

示例:

Section
    ${LineRead} "C:\a.log" "-1" $R0
    ; $R0="Last line$\r$\n"
SectionEnd

E.2.4 FileReadFromEnd

  • 从末尾起逐行读取文本文件

语法:

${FileReadFromEnd} "[File]" "Function"
"[File]"      ; 输入文本文件
"Function"    ; 回调函数
Function "Function"
    ; $9       当前行
    ; $8       当前行号
    ; $7       当前负行号
    ; $R0-$R9 未使用,可用于保存数据
    ; ...
    Push $var      ; 如果 $var="StopFileReadFromEnd" 则退出函数
FunctionEnd

注意:
- 文件不存在时的错误标记

示例1:

Section
    ${FileReadFromEnd} "C:\a.log" "Example1"
    IfErrors 0 +2
    MessageBox MB_OK "错误!"
SectionEnd
Function Example1
    MessageBox MB_OKCANCEL '"Line"=[$9]$\n   "#"=[$8]$\n  "-#"=[$7]' IDOK +2
    StrCpy $0 StopFileReadFromEnd
    Push $0
FunctionEnd

示例2 (保留文本文件):

Section
    GetTempFileName $R0
    FileOpen $R1 $R0 w
    ${FileReadFromEnd} "C:\a.log" "Example2"
    FileClose $R1
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK +2
    Exec '"notepad.exe" "$R0"'
SectionEnd
Function Example2
    StrCmp $7 -1 0 +5
    StrCpy $1 $9 1 -1
    StrCmp $1 '$\n' +3
    StrCmp $1 '$\r' +2
    StrCpy $9 '$9$\r$\n'
    FileWrite $R1 "$9"
    Push $0
FunctionEnd

E.2.5 LineSum

  • 获取文本文件的行数

语法:

${LineSum} "[File]" $var
"[File]"      ; 输入文件
$var          ; 结果:行数

注意:
- 文件不存在时的错误标记

示例:

Section
    ${LineSum} "C:\a.log" $R0
    ; $R0="54"
SectionEnd

E.2.6 FileJoin

  • 将两个文件合并为一个 (File1 + File2 = File3)

语法:

${FileJoin} "[File1]" "[File2]" "[File3]"
"[File1]"     ; 输入文件1
"[File2]"     ; 输入文件2
"[File3]"     ; 输出文件3
              ;  如果 [File3]="" 则增加 [File2] 到 [File1]

注意:
- 输入文件不存在时的错误标记
- 输出文件路径不存在时的错误标记

示例1 (合并:a.log + b.log = Z.log):

Section
    ${FileJoin} "C:\a.log" "C:\logs\b.log" "C:\Z.log"
SectionEnd

示例2 (增加:a.log + b.log = a.log):

Section
    ${FileJoin} "C:\a.log" "C:\logs\b.log" "C:\a.log"
SectionEnd

E.2.7 TextCompare

  • 比较两个文本文件

语法:

${TextCompare} "[File1]" "[File2]" "[Option]" "Function"
"[File1]"     ; File1      比较这些行
"[File2]"     ; File2      与这些行比较
"[Options]"   ; (逐行):
              ; FastDiff   比较第 N 行 (File1) 与第 N 行 (File2),
              ;            如果找到不同行,调用函数。
              ; FastEqual  比较第 N 行 (File1) 与第 N 行 (File2),
              ;            如果找到相同行,调用函数。
              ; (独立行数):
              ; SlowDiff   比较第 N 行 (File1) 与所有行 (File2),
              ;            如果第 N 行 (File1) 不同,调用函数。
              ; SlowEqual  比较第 N 行 (File1) 与所有行 (File2),
              ;            如果第 N 行 (File1) 相同,调用函数。
"Function"    ; 回调函数
Function "Function"
    ; $9    "File1 行"
    ; $8    "行号"
    ; $7    "File2 行" (如果指定 SlowDiff 则为空)
    ; $6    "行号" (如果指定 SlowDiff 则为空)
    ; $R0-$R9 未使用,可用于保存数据
    ; ...
    Push $var    ; 如果 $var="StopTextCompare" 则退出函数
FunctionEnd

注意:
- 文件 1 或文件 2 不存在时的错误标记
- 语法错误时的错误标记

示例 (不同或相等):

Section
    StrCpy $R0 ''
    ${TextCompare} "C:\1.txt" "C:\2.txt" "FastDiff" "Example1"
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK +4
    StrCmp $R0 NotEqual 0 +2
    MessageBox MB_OK "文件不同!" IDOK +2
    MessageBox MB_OK "文件完全相同!"
SectionEnd
Function Example1
    StrCpy $R0 NotEqual
    StrCpy $0 StopTextCompare
    Push $0
FunctionEnd

示例 (逐行比较 - 不同):

Section
    StrCpy $R0 'Text1.txt'
    StrCpy $R1 'Text2.txt'
    GetTempFileName $R2
    FileOpen $R3 $R2 w
    FileWrite $R3 "$R0 | $R1$\r$\n"
    ${TextCompare} "$R0" "$R1" "FastDiff" "Example2"
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK +2
    Exec "notepad.exe $R2"
FunctionEnd
Function Example2
    FileWrite $R3 '$8=$9'
    FileWrite $R3 '$6=$7$\r$\n'
    Push $0
FunctionEnd

示例 (逐行比较 - 相同):

Section
    StrCpy $R0 'Text1.txt'
    StrCpy $R1 'Text2.txt'
    GetTempFileName $R2
    FileOpen $R3 $R2 w
    FileWrite $R3 "$R0 | $R1$\r$\n"
    ${TextCompare} "$R0" "$R1" "FastEqual" "Example3"
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK +2
    Exec "notepad.exe $R2"
FunctionEnd
Function Example3
    FileWrite $R3 '$8|$6=$9'
    Push $0
FunctionEnd

示例 (比较所有行 - 不同):

Section
    StrCpy $R0 'Text1.txt'
    StrCpy $R1 'Text2.txt'
    GetTempFileName $R2
    FileOpen $R3 $R2 w
    FileWrite $R3 "$R0 | $R1$\r$\n"
    ${TextCompare} "$R0" "$R1" "SlowDiff" "Example4"
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK end
    FileWrite $R3 "$\r$\n$R1 | $R0$\r$\n"
    ${TextCompare} "$R1" "$R0" "SlowDiff" "Example4"
    FileClose $R3
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK end
    Exec "notepad.exe $R2"
    end:
FunctionEnd
Function Example4
    FileWrite $R3 '$8=$9'
    Push $0
FunctionEnd

示例 (比较所有行 - 相同):

Section
    StrCpy $R0 'Text1.txt'
    StrCpy $R1 'Text2.txt'
    GetTempFileName $R2
    FileOpen $R3 $R2 w
    FileWrite $R3 "$R0 | $R1$\r$\n"
    ${TextCompare} "$R0" "$R1" "SlowEqual" "Example5"
    IfErrors 0 +2
    MessageBox MB_OK "错误!" IDOK +2
    Exec "notepad.exe $R2"
FunctionEnd
Function Example5
    FileWrite $R3 '$8|$6=$9'
    Push $0
FunctionEnd

示例 (显示变量):

Section
    ${TextCompare} "C:\1.txt" "C:\2.txt" "FastDiff" "Example6"
    IfErrors 0 +2
    MessageBox MB_OK "错误!"
SectionEnd
Function Example6
    MessageBox MB_OKCANCEL '$$9    "文件1行" =[$9]$\n$$8    "行号#"      =[$8]$\n$$7    "文件2行" =[$7]$\n$$6    "行号#"      =[$6]' IDOK +2
    StrCpy $0 StopTextCompare
    Push $0
FunctionEnd

E.2.8 ConfigRead

  • 读取配置文件中项名称的值

语法:

${ConfigRead} "[File]" "[Entry]" $var
"[File]"      ; 配置文件
              ;
"[Entry]"     ; 项名称
              ;
$var          ; 结果:值

注意:
- 文件不存在时的错误标记

示例1:

Section
    ${ConfigRead} "C:\AUTOEXEC.BAT" "SET winbootdir=" $R0
    ;$R0=C:\WINDOWS
SectionEnd

示例2:

Section
    ${ConfigRead} "C:\apache\conf\httpd.conf" "Timeout " $R0
    ;$R0=30
SectionEnd

E.2.9 ConfigWrite

  • 写入配置文件中项名称的值

语法:

${ConfigWrite} "[File]" "[Entry]" "[Value]" $var
"[File]"      ; 配置文件
              ;
"[Entry]"     ; 项名称
              ;
"[Value]"     ; 值名称
              ;  如果为 "" 则删除项
              ;
$var          ; 结果:
              ;    $var=CHANGED  值已写入
              ;    $var=DELETED  项已删除
              ;    $var=ADDED    项和值已添加
              ;    $var=SAME     项和值已存在

注意:
- 文件不存在时的错误标记
- 文件不能打开时的错误标记

示例1:

Section
    ${ConfigWrite} "C:\AUTOEXEC.BAT" "SET winbootdir=" "D:\WINDOWS" $R0
    ;$R0=CHANGED
SectionEnd

示例2:

Section
    ${ConfigWrite} "C:\apache\conf\httpd.conf" "Timeout " "30" $R0
    ;$R0=SAME
SectionEnd

示例3:

Section
    ${ConfigWrite} "C:\apache\conf\httpd.conf" "Timeout " "" $R0
    ;$R0=DELETED
SectionEnd

E.2.10 FileRecode

  • 将文本文件从 DOS 重新编码为 Windows 格式,反之亦然。

语法:

${FileRecode} "[File]" "[Format]"
"[File]"        ;
                ;
"[Format]"      ; OemToChar   - 从 DOS 到 Windows
                ; CharToOem   - 从 Windows 到 DOS

注意:
- 文件不存在时的错误标记
- 语法错误时的错误标记

示例:

Section
    ${FileRecode} "C:\SCANDISK.LOG" "CharToOem"
SectionEnd

E.2.11 TrimNewLines

  • 修剪字符串中的新行

语法:

${TrimNewLines} "[string]" $var
"[string]"    ; 输入字符串
$var          ; 结果:结尾不带 '$\r' 和 '$\n' 的字符串

示例:

Section
    ${TrimNewLines} "文字行$\r$\n" $R0
    ; $R0="文字行"
SectionEnd