2010-08-05 2 views
14

У меня есть исполняемый файл на моем диске-на-ключ в каталоге dir \ program \ prog.exe Я хотел бы иметь ярлык для исполняемого файла в корневом каталоге DoK, то есть prog.lnk будет ссылаться на каталог \ программа \ prog.exe. Однако, похоже, что prog.lnk не может иметь относительную цель. Это проблема, когда у DoK будут назначены разные буквы дисков, в зависимости от того, к какому ПК подключен.Как создать ярлык (.lnk) с относительной целью?

Любые предложения, помимо очевидного размещения prog.exe в корневом каталоге?

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

Спасибо,

Rony

ответ

8

Хотя ярлыки могут содержать относительный путь к цели (файлы .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-файл, что он может читать из себя во время выполнения и т.д ..)

+0

. Документация формата файла .lnk: http://msdn.microsoft.com/en-us/library/dd871305.aspx – n611x007

1

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

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

10

Если мы предположим, cmd.exe бы на том же абсолютный путь для всех окон установок (вероятные, но не дурак-доказательство), вы можете сделать из файла .lnk, чтобы начать ЦМД как этот

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

/д задает каталог для каталог .lnk-файла

Может быть и другое использованиефу l для команды запуска (например,/Б)

3

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

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

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

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

Я использую small tool called "Relative" для этого. После его установки вы можете щелкнуть правой кнопкой мыши файл, а затем выбрать Create relative shortcut.... Затем появится всплывающее окно Save as.... Это не так удобно, как просто перетаскивание, но это помогает. (Он также использует свой собственный значок для создаваемых ссылок. Таким образом, у вас больше нет исходного значка в ссылке. См. Выше. Возможно, вам это может понравиться.)

0

Я считаю, что набор ресурсов NT 4 команда SHORTCUT.exe создаст относительные связанные ярлыки. Я хочу, чтобы Microsoft создала новую поддерживаемую утилиту или командлет Powershell, чтобы облегчить создание относительных файлов .lnk или сделать ссылки NTFS более похожими на символические ссылки Linux. До тех пор я использую файлы .cmd/.bat и .ps1 для этой цели.

Program.cmd

@"%~dp0Relative\Path\Program.exe" %* 
  • @ = Подавляет команду эхо.
  • % ~ dp0 = расширяется до каталога скрипта.
  • Относительный \ Path = может включать .. для резервного копирования каталога.
  • % * = передает любые параметры, полученные скриптом на Program.exe.

Program.ps1

К сожалению, хотя .cmd/BAT-файлы будут работать в любом контексте (диалоговое окно запуска, ЦМД подсказка, в Powershell, двойной щелчок в File Explorer, и т.д.), они не могут вызывать вещи, хранящиеся на пути UNC. Для разоблачения вещей в UNC-пути, в Powershell (я делаю это для таких инструментов, как Git и Mercurial), я создам версию Powershell вышеприведенного скрипта.

&"$PSScriptRoot\Relative\Path\Program.exe" @args 
  • & = помещает Powershell в командный режим, так что строка в кавычках получает побежал.
  • "" = содержит строку, расширяющую любые переменные.
  • $ PSScriptRoot = расширяется до каталога скрипта.
  • Относительный \ Path = может включать .. для резервного копирования каталога.
  • @args = передает любые параметры, полученные скриптом на Program.exe.
Смежные вопросы