E.1 文件函数头文件
优质
小牛编辑
126浏览
2023-12-01
E.1.1 介绍
包含头文件:
!include "FileFunc.nsh"
包含用于安装的 "GetFileExt" 函数和用于卸载的 "GetParent" 函数:
!insertmacro GetFileExt !insertmacro un.GetParent
调用函数:
Section Install ${GetFileExt} "C:\我的下载\Index.html" $R0 ; $R0="html" SectionEnd
Section un.Install ${un.GetParent} "C:\我的下载\Index.html" $R0 ; $R0="C:\My Downloads" SectionEnd
E.1.2 查找
- 使用过滤和大小选项,查找文件、文件夹和空文件夹。
语法:
${Locate} "[Path]" "[Options]" "Function"
"[Path]" ; 磁盘或文件夹 ; "[Options] ; /L=[FD|F|D|DE|FDE] ; /L=FD - 查找文件和文件夹 (默认) ; /L=F - 仅查找文件 ; /L=D - 仅查找文件夹 ; /L=DE - 仅查找空文件夹 ; /L=FDE - 查找文件和空文件夹 ; /M=[mask] ; /M=*.* - 查找全部 (默认) ; /M=*.doc - 查找 Work.doc、1.doc ... ; /M=Pho* - 查找 PHOTOS、phone.txt ... ; /M=win???.exe - 查找 winamp.exe、winver.exe ... ; /M=winamp.exe - 仅查找 winamp.exe ; /S=No:No[B|K|M|G] ; /S= - 不查找文件大小 (较快) (默认) ; /S=0:0B - 精确查找 0 字节的文件 ; /S=5:9K - 仅查找 5~9KB 的文件 ; /S=:10M - 仅查找 10MB 或更小的文件 ; /S=1G - 仅查找 1GB 或更大的文件 ; /G=[1|0] ; /G=1 - 查找子文件夹 (默认) ; /G=0 - 不查找子文件夹 ; /B=[0|1] ; /B=0 - 不使用标语 (默认) ; /B=1 - 使用标语。当函数开始搜索新的文件夹时回调。 "Function" ; 找到时的回调函数 Function "Function" ; $R9 "path\name" ; $R8 "path" ; $R7 "name" ; $R6 "size" ($R6="" 如果是文件夹,$R6="0" 如果是文件 (带 /S= 参数时)) ; $R0-$R5 未使用,可用于保存数据 ; ... ; Push $var ; 如果 $var="StopLocate" 则退出函数 FunctionEnd
注意:
- 文件或文件夹不存在时的错误标记
- 语法错误时的错误标记
示例 (查找一个文件):
Section ${Locate} "C:\ftp" "/L=F /M=RPC DCOM.rar /S=1K" "Example1" ; 文件 'RPC DCOM.rar' 位于 'C:\ftp' 且大小至少为 1KB IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 MessageBox MB_OK "$$R0=$R0" SectionEnd Function Example1 StrCpy $R0 $R9 ; $R0="C:\ftp\files\RPC DCOM.rar" MessageBox MB_YESNO '$R0$\n$\n继续查找?' IDYES +2 StrCpy $0 StopLocate Push $0 FunctionEnd
示例 (将结果写入文本文件):
Section GetTempFileName $R0 FileOpen $R1 $R0 w ${Locate} "C:\ftp" "/S=:2M /G=0" "Example2" ; 文件夹和所有小于 2MB 的文件 ; 不搜寻子文件夹 FileClose $R1 IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 Exec '"notepad.exe" "$R0"' SectionEnd Function Example2 StrCmp $R6 '' 0 +3 FileWrite $R1 "文件夹=$R9$\r$\n" goto +2 FileWrite $R1 "文件=$R9 大小=$R6 MB$\r$\n" Push $0 FunctionEnd
示例 (将结果写入 INI 文件):
Section GetTempFileName $R0 ${Locate} "C:\ftp" "/L=F /S=0K" "Example3" ; 以 KB 为大小单位检测所有位于 'C:\ftp' 的文件 IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 Exec '"notepad.exe" "$R0"' SectionEnd Function Example3 WriteINIStr $R0 "$R8" "$R7" "$R6 KB" Push $0 FunctionEnd
示例 (删除空文件夹):
Section StrCpy $R2 0 StrCpy $R3 0 loop: StrCpy $R1 0 ${Locate} "C:\ftp" "/L=DE" "Example4" IntOp $R3 $R3 + 1 IntOp $R2 $R2 + $R1 StrCmp $R0 StopLocate +2 StrCmp $R1 0 0 loop IfErrors 0 +2 MessageBox MB_OK 'error' IDOK +2 MessageBox MB_OK '已删除 $R2 个文件夹!$\n$R3 次循环。' SectionEnd Function Example4 MessageBox MB_YESNOCANCEL '删除空文件夹 "$R9"?' IDNO end IDCANCEL cancel RMDir $R9 IntOp $R1 $R1 + 1 goto end cancel: StrCpy $R0 StopLocate end: Push $R0 FunctionEnd
示例 (将所有文件移动到一个文件夹):
Section StrCpy $R0 "C:\ftp" ;来源文件夹 StrCpy $R1 "C:\ftp2" ;目标文件夹 StrCpy $R2 0 StrCpy $R3 0 ${Locate} "$R0" "/L=F" "Example5" IfErrors 0 +2 MessageBox MB_OK '错误!' IDOK +4 StrCmp $R3 0 0 +2 MessageBox MB_OK '已移动 $R2 个文件。' IDOK +2 MessageBox MB_OK '已移动 $R2 个文件。$\n$R3 个文件没有移动!' SectionEnd Function Example5 StrCmp $R8 $R1 +6 IfFileExists '$R1\$R7' +4 Rename $R9 '$R1\$R7' IntOp $R2 $R2 + 1 goto +2 IntOp $R3 $R3 + 1 Push $0 FunctionEnd
示例 (带日志复制文件):
Section StrCpy $R0 "C:\ftp" ;来源文件夹 StrCpy $R1 "C:\ftp2" ;目标文件夹 StrLen $R2 $R0 GetTempFileName $0 FileOpen $R3 $0 w ${Locate} "$R0" "/L=FDE" "Example6" FileClose $R3 IfErrors 0 +2 MessageBox MB_OK 'error' Exec '"notepad.exe" "$0"' ;查看日志 SectionEnd Function Example6 StrCpy $1 $R8 '' $R2 StrCmp $R6 '' 0 +3 CreateDirectory '$R1$1\$R7' goto end CreateDirectory '$R1$1' CopyFiles /SILENT $R9 '$R1$1' IfFileExists '$R1$1\$R7' 0 +3 FileWrite $R3 "-old:$R9 -new:$R1$1\$R7 -success$\r$\n" goto +2 FileWrite $R3 "-old:$R9 -new:$R1$1\$R7 -failed$\r$\n" end: Push $0 FunctionEnd
示例 (重新创建文件夹结构):
Section StrCpy $R0 "C:\ftp" ;来源文件夹结构 StrCpy $R1 "C:\ftp2" ;目标文件夹结构 StrLen $R2 $R0 ${Locate} "$R0" "/L=D" "Example7" IfErrors 0 +2 MessageBox MB_OK '错误!' SectionEnd Function Example7 StrCpy $1 $R9 '' $R2 CreateDirectory '$R1$1' Push $0 FunctionEnd
示例 (带标语查找 - 需要 "NxS" 插件):
Section nxs::Show /NOUNLOAD `$(^Name) 安装` /top `安装程序正在搜索某些东西。$\r$\n如果可以,请稍等。` /h 1 /can 1 /end ${Locate} "C:\WINDOWS" "/L=F /M=*.inf /B=1" "Example8" nxs::Destroy SectionEnd Function Example8 StrCmp $R0 $R8 abortcheck StrCpy $R0 $R8 nxs::Update /NOUNLOAD /sub "$R8" /pos 78 /end abortcheck: nxs::HasUserAborted /NOUNLOAD Pop $0 StrCmp $0 1 0 +2 StrCpy $0 StopLocate StrCmp $R9 '' end ;... end: Push $0 FunctionEnd
E.1.3 GetSize
- 查找文件、文件掩码或文件夹的大小
- 查找文件、文件夹和子文件夹的总数量
语法:
${GetSize} "[Path]" "[Options]" $var1 $var2 $var3
"[Path]" ; 磁盘或文件夹 ; "[Options]" ; /M=[mask] ; /M=*.* - 全部查找 (默认) ; /M=*.doc - 查找 Work.doc、1.doc ... ; /M=Pho* - 查找 PHOTOS、phone.txt ... ; /M=win???.exe - 查找 winamp.exe、winver.exe ... ; /M=winamp.exe - 仅查找 winamp.exe ; /S=No:No[B|K|M|G] ; /S= - 不查找文件大小 (较快) (默认) ; /S=0:0B - 仅精确查找 0 字节的文件 ; /S=5:9K - 仅查找 5~9KB 的文件 ; /S=:10M - 仅查找 10MB 或更小的文件 ; /S=1G - 仅查找 1GB 或更大的文件 ; /G=[1|0] ; /G=1 - 查找子文件夹 (默认) ; /G=0 - 不查找子文件夹 ; $var1 ; 结果1:大小 $var2 ; 结果2:文件总数量 $var3 ; 结果3:文件夹总数量
注意:
- 如果磁盘或文件夹不存在时的错误标记
- 语法错误时的错误标记
示例 (1):
Section ; 以 KB 为单位查找文件 "C:\WINDOWS\Explorer.exe" 的大小 ${GetSize} "C:\WINDOWS" "/M=Explorer.exe /S=0K /G=0" $0 $1 $2 ; $0="220" KB ; $1="1" 个文件 ; $2="" 个文件夹 IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd
示例 (2):
Section ; 以 MB 为单位查找文件夹 "C:\Installs\Reanimator\Drivers" 的大小 ${GetSize} "C:\Installs\Reanimator\Drivers" "/S=0M" $0 $1 $2 ; $0="132" MB ; $1="555" 个文件 ; $2="55" 个文件夹 IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd
示例 (3):
Section ; 查找 "C:\WINDOWS" 文件和文件夹的总数量 (不含子文件夹) ${GetSize} "C:\WINDOWS" "/G=0" $0 $1 $2 ; $0="" 大小 ; $1="253" 个文件 ; $2="46" 个文件夹 IfErrors 0 +2 MessageBox MB_OK "错误!" SectionEnd
E.1.4 DriveSpace
- 获取驱动器的全部、已用和可用空间
语法:
${DriveSpace} "[Drive]" "[Options]" $var
"[Drive]" ; 要检查的磁盘 ; "[Options]" ; /D=[T|O|F] ; /D=T - 全部空间 (默认) ; /D=O - 已用空间 ; /D=F - 可用空间 ; /S=[B|K|M|G] ; /S=B - 以字节为大小 (默认) ; /S=K - 以 KB 为大小 ; /S=M - 以 MB 为大小 ; /S=G - 以 GB 为大小 ; $var ; 结果:大小
注意:
- 磁盘不存在或尚未就绪时的错误标记
- 语法错误时的错误标记
示例:
Section ${DriveSpace} "C:\" "/D=F /S=M" $R0 ; $R0="2530" megabytes free on drive C: SectionEnd
E.1.5 GetDrives
- 查找系统中所有可用驱动器
语法:
${GetDrives} "[Option]" "Function"
"[Option]" ; [FDD+HDD+CDROM+NET+RAM] ; FDD 软盘驱动器 ; HDD 硬盘驱动器 ; CDROM 光盘驱动器 ; NET 网络驱动器 ; RAM 虚拟磁盘驱动器 ; ; [ALL] ; 按照字母顺序查找所有驱动器 (默认) "Function" ; 找到时的回调函数 Function "Function" ; $9 "驱动器名称" (a:\ c:\ ...) ; $8 "驱动器类型" (FDD HDD ...) ; $R0-$R9 被使用于储存数据 ; ... Push $var ; 如果 $var="StopGetDrives" 则退出函数 FunctionEnd
示例 1:
Section ${GetDrives} "FDD+CDROM" "Example1" SectionEnd Function Example1 MessageBox MB_OK "$9 ($8 驱动器)" Push $0 FunctionEnd
示例 2:
Section ${GetDrives} "ALL" "Example2" SectionEnd Function Example2 MessageBox MB_OK "$9 ($8 驱动器)" Push $0 FunctionEnd
示例 3 (获取分区类型):
Section StrCpy $R0 "D:\" ;驱动器名称 StrCpy $R1 "invalid" ${GetDrives} "ALL" "Example3" MessageBox MB_OK "驱动器 $R0 的类型为 $R1" SectionEnd Function Example3 StrCmp $9 $R0 0 +3 StrCpy $R1 $8 StrCpy $0 StopGetDrives Push $0 FunctionEnd
E.1.6 GetTime
- 获取本地或系统时间
- 获取文件访问、创建和修改时间
语法:
${GetTime} "[File]" "[Option]" $var1 $var2 $var3 $var4 $var5 $var6 $var7
"[File]" ; 如指定 "L" 或 "LS" 则忽略 ; "[Option]" ; [Options] ; L 本地时间 ; A 文件最后访问时间 ; C 文件创建时间 ; M 文件修改时间 ; LS 系统时间 (UTC) ; AS 文件最后访问时间 (UTC) ; CS 文件创建时间 (UTC) ; MS 文件修改时间 (UTC) ; $var1 ; 结果 1:日 $var2 ; 结果 2:月 $var3 ; 结果 3:年 $var4 ; 结果 4:星期名称 $var5 ; 结果 5:时 $var6 ; 结果 6:分 $var7 ; 结果 7:秒
注意:
- 文件不存在时的错误标记
- 语法错误时的错误标记
示例 (获取本地时间):
Section ${GetTime} "" "L" $0 $1 $2 $3 $4 $5 $6 ; $0="01" 日 ; $1="04" 月 ; $2="2005" 年 ; $3="Friday" 星期名称 ; $4="16" 时 ; $5="05" 分 ; $6="50" 秒 MessageBox MB_OK '日期=$0/$1/$2 ($3)$\n时间=$4:$5:$6' SectionEnd
示例 (获取文件时间):
Section ${GetTime} "$WINDIR\Explorer.exe" "C" $0 $1 $2 $3 $4 $5 $6 ; $0="12" 日 ; $1="10" 月 ; $2="2004" 年 ; $3="Tuesday" 星期名称 ; $4="2" 时 ; $5="32" 分 ; $6="03" 秒 IfErrors 0 +2 MessageBox MB_OK "错误!" IDOK +2 MessageBox MB_OK '日期=$0/$1/$2 ($3)$\n时间=$4:$5:$6' SectionEnd
示例 (获取系统时间):
Section ${GetTime} "" "LS" $0 $1 $2 $3 $4 $5 $6 ; $0="01" 日 ; $1="04" 月 ; $2="2005" 年 ; $3="Friday" 星期名称 ; $4="11" 时 ; $5="05" 分 ; $6="50" 秒 MessageBox MB_OK '日期=$0/$1/$2 ($3)$\n时间=$4:$5:$6' SectionEnd
示例 (将时间转换为 12 小时制 AM/PM):
Section ${GetTime} "" "L" $0 $1 $2 $3 $4 $5 $6 StrCmp $4 0 0 +3 StrCpy $4 12 goto +3 StrCmp $4 12 +5 IntCmp $4 12 0 0 +3 StrCpy $7 AM goto +3 IntOp $4 $4 - 12 StrCpy $7 PM MessageBox MB_OK '日期=$0/$1/$2 ($3)$\n时间=$4:$5:$6 $7' SectionEnd
E.1.7 GetFileAttributes
- 获取文件或文件夹属性
语法:
${GetFileAttributes} "[File]" "[Attributes]" $var
"[File]" ; 文件或文件夹 ; "[Attributes]" ; "ALL" (默认) ; - 输出使用 "|" 连接的所有属性的文件 ; ; "READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE| ; DEVICE|NORMAL|TEMPORARY|SPARSE_FILE|REPARSE_POINT| ; COMPRESSED|OFFLINE|NOT_CONTENT_INDEXED|ENCRYPTED" ; - 文件必须拥有指定的属性 ; $var ; 结果: ; $var=attr1|attr2|... (如果使用了 "ALL") ; $var=1 文件拥有指定属性 ; $var=0 文件没有指定属性
注意:
- 文件不存在时的错误标记
示例1:
Section ${GetFileAttributes} "C:\MSDOS.SYS" "ALL" $R0 ; $R0=READONLY|HIDDEN|SYSTEM|ARCHIVE SectionEnd
示例2:
Section ${GetFileAttributes} "C:\MSDOS.SYS" "SYSTEM|HIDDEN" $R0 ; $R0=1 SectionEnd
示例3:
Section ${GetFileAttributes} "C:\MSDOS.SYS" "NORMAL" $R0 ; $R0=0 SectionEnd
E.1.8 GetFileVersion
- 获取可执行文件的版本信息
语法:
${GetFileVersion} "[Executable]" $var
"[Executable]" ; 可执行文件 (*.exe *.dll ...) $var ; 结果:版本号
注意:
- 文件不存在时的错误标记
- 文件不含版本信息时的错误标记
示例:
Section ${GetFileVersion} "C:\ftp\program.exe" $R0 ; $R0="1.1.0.12" SectionEnd
E.1.9 GetExeName
- 获取安装程序文件名 (在Windows 98/ME 下包括有效用例)
语法:
${GetExeName} $var
示例:
Section ${GetExeName} $R0 ; $R0="C:\ftp\program.exe" SectionEnd
E.1.10 GetExePath
- 获取安装程序路径 (在 Windows 98/ME 下 $EXEDIR 包括有效用例)
语法:
${GetExePath} $var
示例:
Section ${GetExePath} $R0 ; $R0="C:\ftp" SectionEnd
E.1.11 GetParameters
- 获取命令行参数
语法:
${GetParameters} $var
示例:
Section ${GetParameters} $R0 ; $R0="[parameters]" SectionEnd
E.1.12 GetOptions
- 获取命令行参数中的选项
语法:
${GetOptions} "[Parameters]" "[Option]" $var
"[Parameters]" ; 命令行参数 ; "[Option]" ; 选项名称 ; $var ; 结果:选项字符串
注意:
- 第一个选项符号为分隔符
示例 1:
Section ${GetOptions} "/INSTDIR=Temp /SILENT=yes /ADMIN=qwerty" "/ADMIN=" $R0 ;$R0=qwerty SectionEnd
示例 2:
Section ${GetOptions} "-INSTDIR=C:\Program Files\Common Files -SILENT=yes" "-INSTDIR=" $R0 ;$R0=C:\Program Files\Common Files SectionEnd
示例 3:
Section ${GetOptions} '/SILENT=yes /INSTDIR="C:/Program Files/Common Files" /ADMIN=password' "/INSTDIR=" $R0 ;$R0=C:/Program Files/Common Files SectionEnd
示例 4:
Section ${GetOptions} `-SILENT=yes -INSTDIR='"C:/Program Files/Common Files"' -ADMIN=password` "-INSTDIR=" $R0 ;$R0="C:/Program Files/Common Files" SectionEnd
E.1.13 GetRoot
- 获取根路径
语法:
${GetRoot} "[FullPath]" $var
示例 1:
Section ${GetRoot} "C:\Program Files\NSIS" $R0 ; $R0="C:" SectionEnd
示例 2:
Section ${GetRoot} "\\SuperPimp\NSIS\Source\exehead\Ui.c" $R0 ; $R0="\\SuperPimp\NSIS" SectionEnd
E.1.14 GetParent
- 获取父路径
语法:
${GetParent} "[PathString]" $var
示例:
Section ${GetParent} "C:\Program Files\Winamp\uninstwa.exe" $R0 ; $R0="C:\Program Files\Winamp" SectionEnd
E.1.15 GetFileName
- 获取文件夹路径中的最后一部分
语法:
${GetFileName} "[PathString]" $var
示例:
Section ${GetFileName} "C:\Program Files\Winamp\uninstwa.exe" $R0 ; $R0="uninstwa.exe" SectionEnd
E.1.16 GetBaseName
- 获取文件名不带扩展名
语法:
${GetBaseName} "[FileString]" $var
示例:
Section ${GetBaseName} "C:\ftp\program.exe" $R0 ; $R0="program" SectionEnd
E.1.17 GetFileExt
- 获取文件扩展名
语法:
${GetFileExt} "[FileString]" $var
示例:
Section ${GetFileExt} "C:\ftp\program.exe" $R0 ; $R0="exe" SectionEnd
E.1.18 BannerTrimPath
- 为标语修剪路径
语法:
${BannerTrimPath} "[PathString]" "[Option]" $var
"[PathString]" ; ; "[Option]" ; [Length][A|B|C|D] ; ; Length - 最大字符串长度 ; A - 修剪中间路径 (默认) ; (C:\root\...\third path) ; 如果 A 模式不可能将使用 B 模式 ; B - 修剪右侧路径 ; (C:\root\second path\...) ; 如果 B 模式不可能将使用 C 模式 ; C - 右键右侧字符串 ; (C:\root\second path\third p...) ; D - 右键右侧字符串和文件名 ; (C:\root\second p...\third path) ; 如果 D 模式不可能则使用 C 模式 ; $var ; 结果:已修剪路径
示例:
Section ${BannerTrimPath} "C:\Server\Documents\Terminal\license.htm" "35A" $R0 ;$R0=C:\Server\...\Terminal\license.htm SectionEnd
示例 (Banner 插件):
!include "WinMessages.nsh" !include "FileFunc.nsh" !insertmacro Locate Section Banner::show /NOUNLOAD "准备开始..." Banner::getWindow /NOUNLOAD Pop $R1 ${Locate} "$WINDIR" "/L=F /M=*.* /B=1" "LocateCallback" Banner::destroy SectionEnd Function LocateCallback StrCmp $R0 $R8 code StrCpy $R0 $R8 ${BannerTrimPath} "$R8" "38B" $R8 GetDlgItem $1 $R1 1030 SendMessage $1 ${WM_SETTEXT} 0 "STR:$R8" code: StrCmp $R9 '' end ;... end: Push $0 FunctionEnd
示例 (NxS 插件):
!include "FileFunc.nsh" !insertmacro Locate Section nxs::Show /NOUNLOAD `$(^Name) 安装`\ /top `安装程序正在搜索某些东西。$\r$\n如果可以,请稍等。`\ /h 1 /can 1 /end ${Locate} "$WINDIR" "/L=F /M=*.* /B=1" "LocateCallback" nxs::Destroy SectionEnd Function LocateCallback StrCmp $R0 $R8 abortcheck StrCpy $R0 $R8 ${BannerTrimPath} "$R8" "55A" $R8 nxs::Update /NOUNLOAD /sub "$R8" /pos 78 /end abortcheck: nxs::HasUserAborted /NOUNLOAD Pop $0 StrCmp $0 1 0 +2 StrCpy $0 StopLocate StrCmp $R9 '' end ;... end: Push $0 FunctionEnd
E.1.19 DirState
- 检查文件夹是满、空还是不存在
语法:
${DirState} "[path]" $var
"[path]" ; 文件夹 $var ; 结果: ; $var=0 (空) ; $var=1 (满) ; $var=-1 (文件夹未找到)
示例:
Section ${DirState} "$TEMP" $R0 ; $R0="1" 文件夹已满 SectionEnd
E.1.20 RefreshShellIcons
- 当修改文件关联后,你可以调用这个函数立即刷新程序。
语法:
${RefreshShellIcons}
示例:
Section WriteRegStr HKCR "Winamp.File\DefaultIcon" "" "$PROGRAMFILES\Winamp\WINAMP.EXE,2" ${RefreshShellIcons} SectionEnd