Как создать ярлык (.lnk) с относительной целью?

У меня есть исполняемый файл на моем диске-на-ключе в dirprogramprog.исполняемый Я хотел бы иметь ярлык для исполняемого файла в корневом каталоге DoK, то есть prog.lnk будет ссылаться на dirprogramprog.исполняемый.

однако, кажется, что prog.у lnk не может быть относительной цели. Это проблема, когда DoK будет иметь разные буквы диска, назначенные ему, в зависимости от того, к какому ПК он подключен.

любые предложения, кроме очевидного одного из прог.exe в root dir?

(в конечном счете, я хотел бы сделать это во время установки с помощью nsis)

спасибо,

Рони

5 ответов


в то время как ярлыки могут содержать относительный путь к цели (.файлы lnk имеют флаг SLDF_HAS_RELPATH) NSIS не поддерживает создание ничего, кроме" обычных " ярлыков, поэтому вам нужно написать двоичные данные напрямую (The .формат lnk довольно стабилен и был задокументирован MS)

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


Function CreateRelativeLnk
exch 
exch
exch 
push 
FileOpen  "" 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

назовем это так:

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

пока генерируется .lnk, похоже, работает, я не уверен, буду ли я использовать это в производстве код

гораздо лучшее решение-создать небольшое приложение NSIS, как предлагает Олег (приложения NSIS могут содержать встроенные данные в конце.exe, который он может читать из себя во время выполнения и т. д..)


если предположить cmd.exe будет на том же абсолютном пути для всех установок windows (вероятно, но не безрассудно), которые вы можете разобрать .LNK файл для запуска cmd, как это

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

/ d устанавливает каталог в каталог .файл LNK

могут быть и другие полезные опции для команды start (например, /b)


Установить "Relative"

я использую немного взломать. Подход показан на этом скриншоте:

он запускает explorer.exe, а затем передает относительные путь вот так:

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

я использую маленький инструмент под названием "относительный" для этого. После его установки можно щелкнуть правой кнопкой мыши файл и выбрать Create relative shortcut.... Затем он появится


вы правы. Вы не можете использовать ярлыки (.ЛНК) на съемный носитель, так как вы сами написали съемный носитель может иметь разные буквы в разных ситуациях.

Если вам нужно что-то в корневом каталоге диска, используйте CMD, VBS или JS вместо ярлыка. В какой-то ситуации можно использовать также стандартный EXE, который использует файл конфигурации, такой как INI file, чтобы запустить другую программу из другого подкаталога. Это типичная практика для CD / DVD реализовать запуск программы установки после вставки диска. Вероятно, этот способ будет в порядке и для ваших требований?


Я считаю, что команда NT 4 Resource Kit ярлык.exe создаст относительные связанные ярлыки. Я хочу, чтобы Microsoft создала новую поддерживаемую утилиту или командлет Powershell для облегчения создания relative .файлы lnk или ссылки NTFS работают больше как символические ссылки Linux. До тех пор я использую .УМК./BAT и .файлы PS1 для этой цели.