这个问题是前几天群里一位群友提出的问题,如何使用nsis获取符号链接的实际路径,说实话当时还是有点蒙的,因为NSIS作为一个软件安装包制作的脚本系统,这种应用场景还是非常少的,并且NSIS天生就不支持操作系统的高级文件系统功能!所以问题就显得比较生僻!后来又去恶补了一下关于符号链接的工作原理和相关资料,发现目前为止,关于nsis操作软连接的教程和资料在国内外还是个空白,所以决定写一篇关于这方面的博文刷下存在感。

话归正题,因为NSIS本身不支持高级文件系统功能,所以开始考虑使用winAPI来进行操作,文中涉及三个api函数,CreateFile,CreateSymbolicLink和GetFinalPathNameByHandle,前两个是为了方便功能演示而创建的源文件及其符号链接,重点在第三个函数GetFinalPathNameByHandle,它是实现获取符号链接实际路径的关键!几经调试修改,范例脚本完成。

注意,这不是生产样本,提供的只是一种思路与功能完成途径,应用中需要自己再去完善各种运行条件和环境判断!

#获取符号链接实际路径
!include "FileFunc.nsh"
#编写:水晶石
OutFile 'Nsistest.exe'

Section
#创建源文件
StrCpy $R0 C:\example
StrCpy $R1  D:\softlink
CreateDirectory $R0
System::Call "kernel32::CreateFile(t `$R0\a.txt`, i 0x40, i 0, i 0, i 4, i 0, i 0) p .r0"
#创建软连接,$R1为软连接
System::Call "kernel32::CreateSymbolicLink(t `$R1`, t `$R0`, i 0x1) i .s"
#读取创建的软连接源文件目标位置
FileOpen $0 $R1\a.txt r
System::StrAlloc 64
Pop $3
System::Call "kernel32::GetFinalPathNameByHandle(p r0, t.r1, i r3,i0x0)i.r2"
System::Call "kernel32::CloseHandle(p r0) i.s"
StrCpy $1 "$1" "" 4
${GetParent} "$1" $1
MessageBox MB_OK "源文件目录为:$1"
System::Free $3
SectionEnd

10-13 14:27