windows 如何使用相对目标创建快捷方式 (.lnk)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3418541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a shortcut (.lnk) with a relative target?
提问by ronys
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.
我在 dir\program\prog.exe 中的磁盘上有一个可执行文件。可执行程序。
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.lnk 似乎不能有相对目标。当 DoK 将分配不同的驱动器号时,这是一个问题,具体取决于它连接到的 PC。
Any suggestions, aside from the obvious one of putting prog.exe in the root dir?
除了将 prog.exe 放在根目录中的明显建议之外,还有什么建议吗?
(ultimately, I'd like to do this at install time using nsis)
(最终,我想在安装时使用 nsis 执行此操作)
Thanks,
谢谢,
Rony
罗尼
采纳答案by Anders
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)
虽然快捷方式可能包含目标的相对路径(.lnk 文件有一个名为SLDF_HAS_RELPATH的标志)NSIS 不支持创建除“正常”快捷方式以外的任何内容,因此您需要直接写入二进制数据(.lnk 格式非常稳定,并已被 MS 记录)
!macro FileWriteHexBytes h b
push ${h}
push ${b}
call FileWriteHexBytes
!macroend
Function FileWriteHexBytes
exch
exch
exch push "$temp\testlink.lnk"
push "testdir\testapp.exe" ;full path to this is $temp\testdir\testapp.exe
call CreateRelativeLnk
push
push
loop:
StrCpy 2
StrLen
IntCmp 2 0 end
FileWriteByte cmd.exe /c start /d. your command here
"0x"
StrCpy "" 2
goto loop
end:
pop
pop
pop %windir%\explorer.exe path\to\your\files\youFileName.example
pop
FunctionEnd
Function CreateRelativeLnk
exch
exch
exch @"%~dp0Relative\Path\Program.exe" %*
push
FileOpen &"$PSScriptRoot\Relative\Path\Program.exe" @args
"##代码##" w
StrCmp ##代码## "" clean
!insertmacro FileWriteHexBytes ##代码## "4C0000000114020000000000C000000000000046"
!insertmacro FileWriteHexBytes ##代码## 48010400 ;flags
!insertmacro FileWriteHexBytes ##代码## 00000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000
StrLen ;must be < 255!
FileWriteByte ##代码##
FileWriteByte ##代码## 0
FileWrite ##代码## "" ;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 "explorer.exe"
StrLen
FileWriteByte ##代码##
FileWriteByte ##代码## 0
FileWrite ##代码## ""
!else
!insertmacro FileWriteHexBytes ##代码## 05003e2e657865 ;fake default .exe icon
!endif
clean:
FileClose ##代码##
pop
pop ##代码##
pop
FunctionEnd
Call it like this:
像这样调用它:
##代码##While the generated .lnk seems to work, I'm not sure if I would use this in production code
虽然生成的 .lnk 似乎有效,但我不确定是否会在生产代码中使用它
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..)
一个更好的解决方案是创建一个像 Oleg 建议的小 NSIS 应用程序(NSIS 应用程序可以在 .exe 的末尾包含嵌入的数据,它可以在运行时从自身读取等等。)
回答by Elijah
If we assume cmd.exe would be on the same absolute path for all windows installations (probable, but not fool-proof) you can make out the .lnk file to start cmd like this
如果我们假设 cmd.exe 将位于所有 Windows 安装的相同绝对路径上(可能,但不是万无一失),您可以制作 .lnk 文件以启动 cmd 像这样
##代码##/d sets the directory to the directory of the .lnk file
/d 将目录设置为 .lnk 文件的目录
There might be other useful options for the start command (e.g. /b)
启动命令可能还有其他有用的选项(例如 /b)
回答by basil
Install "Relative"
安装“相对”
I'm using a bit of a hack. The approach is shown in this screenshot:
我正在使用一些黑客。该方法显示在此屏幕截图中:
It starts explorer.exe and then passes a relativepath like so:
它启动 explorer.exe,然后传递一个相对路径,如下所示:
##代码##I'm using a small tool called "Relative"for this. After you install it, you can right-click a file and then select Create relative shortcut...
. It will then pop up a Save as...
box. This is not quite as comfortable as simply dragging and dropping but it helps. (It also uses its own special icon for the links it creates. So you no longer have the original icon in the link. See above. You may or may not like this.)
为此,我使用了一个名为“Relative”的小工具。安装后,您可以右键单击文件,然后选择Create relative shortcut...
. 然后它会弹出一个Save as...
框。这不像简单的拖放那样舒服,但它有帮助。(它还为它创建的链接使用自己的特殊图标。因此,链接中不再有原始图标。见上文。您可能喜欢也可能不喜欢。)
回答by Oleg
You are right. You can not use shortcuts (.lnk) on a removable media, because like you wrote yourself the removable media can have different drive letters in different situations.
你是对的。您不能在可移动媒体上使用快捷方式 (.lnk),因为就像您自己编写的那样,可移动媒体在不同情况下可能具有不同的驱动器号。
If you need to have something in a root directory of the drive one use a CMD, VBS or JS instead of a shortcut. In some situation one use also a standard EXE which use a config file like INI file to start another program from the other subdirectory. It is a typical practice for CD/DVD to implement starting of a setup program after inserting of the disk. Probably this way will be OK in for your requirements also?
如果您需要在驱动器的根目录中放置某些内容,请使用 CMD、VBS 或 JS 而不是快捷方式。在某些情况下,还使用标准 EXE,它使用像 INI 文件这样的配置文件从另一个子目录启动另一个程序。CD/DVD 实现插入光盘后启动安装程序是典型的做法。可能这种方式也可以满足您的要求?
回答by Nathan Hartley
I believe that the NT 4 Resource Kit command SHORTCUT.exewould create relative linked shortcuts. I wish that Microsoft would create a new supported utility or Powershell Cmdlet to facilitate the creation of relative .lnk files or make NTFS links work more like Linux symbolic links. Until then, I use .cmd/.bat and .ps1 files for this purpose.
我相信 NT 4 Resource Kit 命令SHORTCUT.exe会创建相对链接的快捷方式。我希望 Microsoft 能够创建一个新的受支持的实用程序或 Powershell Cmdlet,以促进相关 .lnk 文件的创建或使 NTFS 链接更像 Linux 符号链接。在那之前,我为此使用 .cmd/.bat 和 .ps1 文件。
Program.cmd
程序.cmd
##代码##- @ = Suppresses the command echo.
- %~dp0 = expands to the script's directory.
- Relative\Path = could include .. to backup a directory.
- %* = passes any parameters received by the script on to Program.exe.
- @ = 抑制命令回显。
- %~dp0 = 扩展到脚本的目录。
- Relative\Path = 可以包含 .. 来备份目录。
- %* = 将脚本接收到的任何参数传递给 Program.exe。
Program.ps1
程序.ps1
Unfortunately, though .cmd/.bat files will run from any context (the run dialog, a CMD prompt, in Powershell, double clicking in File Explorer, etc), they cannot call things stored on a UNC path. For exposing things in a UNC path, in Powershell (I do this for tools like Git and Mercurial), I will create a Powershell version of the above script.
不幸的是,尽管 .cmd/.bat 文件可以从任何上下文(运行对话框、CMD 提示、Powershell、双击文件资源管理器等)运行,但它们不能调用存储在 UNC 路径上的东西。为了在 UNC 路径中公开内容,在 Powershell 中(我为 Git 和 Mercurial 等工具执行此操作),我将创建上述脚本的 Powershell 版本。
##代码##- & = puts Powershell into command mode, so that the string in quotes gets ran.
- "" = contains a string, expanding any variables.
- $PSScriptRoot = expands to the script's directory.
- Relative\Path = could include .. to backup a directory.
- @args = passes any parameters received by the script on to Program.exe.
- & = 将 Powershell 置于命令模式,以便运行引号中的字符串。
- "" = 包含一个字符串,可扩展任何变量。
- $PSScriptRoot = 扩展到脚本的目录。
- Relative\Path = 可以包含 .. 来备份目录。
- @args = 将脚本接收到的任何参数传递给 Program.exe。