Как создать ярлык (.lnk) с относительной целью?
У меня есть исполняемый файл на моем диске на ключ в каталоге \program\prog.exe
Я хотел бы иметь ярлык для исполняемого файла в корневом каталоге DoK, то есть prog.lnk будет ссылаться на dir\program\prog.exe.
Однако, похоже, что prog.lnk не может иметь относительную цель. Это проблема, когда DoK будет иметь разные буквы дисков, назначенные ему, в зависимости от того, к какому ПК он подключен.
Любые предложения, помимо очевидного размещения prog.exe в корневом каталоге?
(в конечном счете, я хотел бы сделать это во время установки с помощью nsis)
Спасибо,
Рони
Ответы
Ответ 1
Хотя ярлыки могут содержать относительный путь к цели (файлы .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, похоже, работает, я не уверен, буду ли я использовать его в производственном коде
Лучшим решением является создание небольшого приложения NSIS, такого как Олег (приложения NSIS могут содержать встроенные данные в конце .exe, которые он может читать от себя во время выполнения и т.д.).
Ответ 2
Если мы предположим, что cmd.exe будет на одном и том же абсолютном пути для всех оконных установок (вероятно, но не проверен дураком), вы можете разглядеть файл .lnk, чтобы запустить cmd, как этот
cmd.exe /c start /d. your command here
/d устанавливает каталог в каталог .lnk файла
Могут быть другие полезные параметры для команды запуска (например,/b)
Ответ 3
Установите "Относительный"
Я использую немного взлома. Этот снимок показан на этом скриншоте: ![]()
Он запускает explorer.exe и затем передает относительный путь следующим образом:
%windir%\explorer.exe path\to\your\files\youFileName.example
Я использую для этого небольшой инструмент маленький инструмент под названием "Относительный" . После его установки вы можете щелкнуть правой кнопкой мыши файл и выбрать Create relative shortcut...
. Затем появится окно Save as...
. Это не так удобно, как просто перетаскивание, но это помогает. (Он также использует свой собственный специальный значок для создаваемых ссылок. Таким образом, у вас больше нет исходного значка в ссылке. См. Выше. Возможно, вам может или не понравится.)
Ответ 4
Вы правы. Вы не можете использовать ярлыки (.lnk) на съемном носителе, потому что, как вы сами написали, съемный носитель может иметь разные буквы дисков в разных ситуациях.
Если вам нужно что-то в корневом каталоге диска, используйте вместо него ярлык CMD, VBS или JS. В какой-то ситуации используется также стандартный EXE, который использует файл конфигурации, такой как INI файл, для запуска другой программы из другого подкаталога. Это типичная практика для CD/DVD для запуска запуска программы установки после вставки диска. Вероятно, этот способ также подходит для ваших требований?
Ответ 5
Я считаю, что команда NT 4 Resource Kit SHORTCUT.exe создаст относительные связанные ярлыки. Я хочу, чтобы Microsoft создала новую поддерживаемую утилиту или командлет Powershell, чтобы облегчить создание относительных файлов .lnk или сделать ссылки NTFS более похожими на символические ссылки Linux. До тех пор я использую файлы .cmd/.bat и .ps1 для этой цели.
Program.cmd
@"%~dp0Relative\Path\Program.exe" %*
- @= Подавляет эхо команды.
- % ~ dp0 = расширяется до каталога script.
- Relative\Path = может включать.. для резервного копирования каталога.
- % * = передает любые параметры, полученные с помощью script на Program.exe.
Program.ps1
К сожалению, хотя файлы .cmd/.bat будут запускаться из любого контекста (диалог запуска, приглашение CMD, в Powershell, двойной щелчок в Проводнике и т.д.), они не могут вызывать вещи, хранящиеся на пути UNC. Чтобы разоблачить вещи в UNC-пути, в Powershell (я делаю это для таких инструментов, как Git и Mercurial), я создам версию Powershell выше script.
&"$PSScriptRoot\Relative\Path\Program.exe" @args
- & = помещает Powershell в командный режим, так что строка в кавычках запускается.
- "" = содержит строку, расширяющую любые переменные.
- $PSScriptRoot = расширяется до каталога script.
- Relative\Path = может включать.. для резервного копирования каталога.
- @args = передает любые параметры, полученные с помощью script на Program.exe.