Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a shortcut (.lnk) with a relative target?

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

like image 303
ronys Avatar asked Aug 05 '10 19:08

ronys


People also ask

Are LNK files shortcuts?

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.

How do I create a shortcut to a file path?

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.

What are target shortcuts?

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.


3 Answers

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)

like image 86
Elijah Avatar answered Oct 31 '22 06:10

Elijah


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..)

like image 45
Anders Avatar answered Oct 31 '22 04:10

Anders


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 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.)

like image 3
basil Avatar answered Oct 31 '22 06:10

basil