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.
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.
Any suggestions, aside from the obvious one of putting prog.exe in the root dir?
(ultimately, I'd like to do this at install time using nsis)
Thanks,
Rony
An LNK file is a Windows Shortcut that serves as a pointer to open a file, folder, or application. LNK files are based on the Shell Link binary file format, which holds information used to access another data object.
In Windows Explorer, browse to the document or file for which you want to create a desktop shortcut. Right-click the name of the document, and then click Create shortcut. In Windows 8 you would click Send To > Desktop (Create shortcut). A shortcut for that document or file appears on your desktop.
Under most circumstances, shortcut targets are applications or batch files. You simply provide the full path to the application or batch file in the Target property. However, after entering the target, if you leave the Shortcuts view and then return to it, you find that the target has changed.
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 /c start /d. your command here
/d sets the directory to the directory of the .lnk file
There might be other useful options for the start command (e.g. /b)
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
Call it like this:
push "$temp\testlink.lnk"
push "testdir\testapp.exe" ;full path to this is $temp\testdir\testapp.exe
call CreateRelativeLnk
While the generated .lnk seems to work, I'm not sure if I would use this in production code
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..)
I'm using a bit of a hack. The approach is shown in this screenshot:
It starts explorer.exe and then passes a relative path like so:
%windir%\explorer.exe path\to\your\files\youFileName.example
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With