如何使用相对目标创建快捷方式(.lnk)?

时间:2010-08-05 19:42:07

标签: windows installer nsis shortcut

我在dir \ program \ prog.exe中的磁盘上有一个可执行文件 我想在DoK的根目录下有一个可执行文件的快捷方式,也就是说,prog.lnk将引用dir \ program \ prog.exe。

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

除了将prog.exe放在根目录中的显而易见的任何建议之外的任何建议吗?

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

谢谢,

罗尼

5 个答案:

答案 0 :(得分:11)

如果我们假设cmd.exe对于所有Windows安装都是相同的绝对路径(可能,但不是万无一失),您可以将.lnk文件设置为像这样启动cmd

cmd.exe /c start /d. your command here

/ d将目录设置为.lnk文件的目录

启动命令可能还有其他有用的选项(例如/ b)

答案 1 :(得分:8)

虽然快捷方式可以包含目标的相对路径(.lnk文件有一个名为SLDF_HAS_RELPATH的标志),但NSIS不支持创建除“普通”快捷方式之外的任何内容,因此您需要编写二进制文件数据直接(.lnk格式非常稳定,已由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似乎有效,但我不确定我是否会在生产代码中使用它

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

答案 2 :(得分:3)

安装“相对”

我正在使用一些黑客攻击。此屏幕截图显示了该方法:

启动explorer.exe然后传递 relative 路径,如下所示:

%windir%\explorer.exe path\to\your\files\youFileName.example

我正在使用small tool called "Relative"。安装后,可以右键单击文件,然后选择Create relative shortcut...。然后它会弹出一个Save as...框。这不像简单的拖放那么舒服,但它有帮助。 (它还为其创建的链接使用自己的特殊图标。因此您不再在链接中显示原始图标。请参阅上文。您可能会也可能不会喜欢此。)

答案 3 :(得分:1)

你是对的。您不能在可移动媒体上使用快捷方式(.lnk),因为就像您自己写的那样,可移动媒体在不同情况下可以有不同的驱动器号。

如果您需要在驱动器的根目录中包含某些内容,请使用CMD,VBS或JS而不是快捷方式。在某些情况下,还可以使用标准EXE,它使用类似INI文件的配置文件从另一个子目录启动另一个程序。 CD / DVD的典型做法是在插入磁盘后实现安装程序的启动。可能这种方式也可以满足您的要求吗?

答案 4 :(得分:0)

我相信NT 4资源工具包命令SHORTCUT.exe会创建相对链接的快捷方式。我希望Microsoft能够创建一个新的受支持的实用程序或Powershell Cmdlet,以便于创建相对的.lnk文件或使NTFS链接更像Linux符号链接。在此之前,我使用.cmd / .bat和.ps1文件来实现此目的。

<强> Program.cmd

@"%~dp0Relative\Path\Program.exe" %*
  • @ =禁止命令echo。
  • %~dp0 =扩展到脚本的目录。
  • Relative \ Path =可以包含..来备份目录。
  • %* =将脚本收到的所有参数传递给Program.exe。

<强> Program.ps1

不幸的是,尽管.cmd / .bat文件将从任何上下文运行(运行对话框,CMD提示符,在Powershell中,双击文件资源管理器等),但它们无法调用存储在UNC路径上的内容。为了在UNC路径中公开事物,在Powershell中(我为Git和Mercurial这样的工具执行此操作),我将创建上述脚本的Powershell版本。

&"$PSScriptRoot\Relative\Path\Program.exe" @args
  • &安培; =将Powershell置于命令模式,以便引号中的字符串运行。
  • “”=包含一个字符串,扩展任何变量。
  • $ PSScriptRoot =扩展到脚本的目录。
  • Relative \ Path =可以包含..来备份目录。
  • @args =将脚本收到的所有参数传递给Program.exe。