如何创建具有相对目标的快捷方式(.lnk)? [英] How do I create a shortcut (.lnk) with a relative target?

查看:205
本文介绍了如何创建具有相对目标的快捷方式(.lnk)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在dir \ program \ prog.exe的密钥磁盘上有一个可执行文件 我想在DoK的根目录上找到可执行文件的快捷方式,即prog.lnk将指向dir \ program \ prog.exe.

I have an executable on my disk-on-key in dir\program\prog.exe I'd like to have a shortcut to the executable on the DoK's root directory, that is, prog.lnk would refer to dir\program\prog.exe.

但是,似乎prog.lnk不能有相对目标.当DoK将为其分配不同的驱动器号(取决于所连接的PC)时,这是一个问题.

However, it seems that prog.lnk can't have a relative target. This is a problem when the DoK will have different drive letters assigned to it, depending on which PC it's connected to.

除了将prog.exe放在根目录中这一显而易见的建议之外,还有其他建议吗?

Any suggestions, aside from the obvious one of putting prog.exe in the root dir?

(最终,我想在安装时使用nsis进行此操作)

(ultimately, I'd like to do this at install time using nsis)

谢谢

罗尼

推荐答案

虽然快捷方式有可能包含指向目标的相对路径(.lnk文件具有名为

While it is possible for shortcuts to contain a relative path to the target (.lnk files have a flag called SLDF_HAS_RELPATH) NSIS does not support creating anything other than "normal" shortcuts so you need to write the binary data directly (The .lnk format is pretty stable and has been documented by MS)

!macro FileWriteHexBytes h b
push ${h}
push ${b}
call FileWriteHexBytes
!macroend
Function FileWriteHexBytes
exch $9
exch
exch $0
push $1
push $2
loop:
    StrCpy $2 $9 2
    StrLen $1 $2
    IntCmp $1 2 0 end
    FileWriteByte $0 "0x$2"
    StrCpy $9 $9 "" 2
    goto loop
end:
pop $2
pop $1
pop $0
pop $9
FunctionEnd


Function CreateRelativeLnk
exch $9
exch
exch $0
push $1
FileOpen $0 "$0" w
StrCmp $0 "" clean
!insertmacro FileWriteHexBytes $0 "4C0000000114020000000000C000000000000046"
!insertmacro FileWriteHexBytes $0 48010400 ;flags
!insertmacro FileWriteHexBytes $0 00000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000

StrLen $1 $9 ;must be < 255!
FileWriteByte $0 $1
FileWriteByte $0 0
FileWrite $0 "$9" ;relative target path

!if 0
;The icon is problematic, does not seem like it works with relative paths (but you can use system icons...)
StrCpy $9 "explorer.exe"
StrLen $1 $9
FileWriteByte $0 $1
FileWriteByte $0 0
FileWrite $0 "$9"
!else
!insertmacro FileWriteHexBytes $0 05003e2e657865 ;fake default .exe icon
!endif

clean:
FileClose $0
pop $1
pop $0
pop $9
FunctionEnd

这样称呼:

push "$temp\testlink.lnk"
push "testdir\testapp.exe" ;full path to this is $temp\testdir\testapp.exe
call CreateRelativeLnk

虽然生成的.lnk似乎可以工作,但是我不确定是否要在生产代码中使用它.

While the generated .lnk seems to work, I'm not sure if I would use this in production code

一个更好的解决方案是像Oleg建议的那样创建一个小的NSIS应用程序(NSIS应用程序可以在.exe的末尾包含嵌入式数据,并可以在运行时从其自身读取等等.)

A much better solution is to create a little NSIS app like Oleg suggests (NSIS applications can contain embedded data at the end of the .exe that it can read from itself at runtime etc..)

这篇关于如何创建具有相对目标的快捷方式(.lnk)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆