powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Путь до объекта по ярлыку (FileGetSymLinkTarget)
16 сообщений из 16, страница 1 из 1
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39541626
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
procedure Test;
var
  S: string;
begin
  if (FileGetSymLinkTarget('C:\Users\Дмитрий\Desktop\Delphi 10.1 Berlin.lnk', S)) then
    ShowMessage(S)
  else
    ShowMessage('none');
end;



Показывается "none"
Что я делаю не так?

В интернете увидел вот такую штуку (типа особенная реализация под винду). Но возвращается фигня.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
function FileGetSymLinkTarget(const FileName: string; var TargetName: string): Boolean;
var
  LinkHandle: THandle;
  Buffer: array [0..512] of Char;
begin
  Result := False;

  LinkHandle := CreateFile(PChar(FileName), 0, FILE_SHARE_READ, nil,
      OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
  if (LinkHandle <> INVALID_HANDLE_VALUE) then
  try
    if (GetFinalPathNameByHandle(LinkHandle, Buffer, High(Buffer), FILE_NAME_NORMALIZED) > 0) then
    begin
      TargetName := Buffer;
      Result := True;
    end;
  finally
    CloseHandle(LinkHandle);
  end;
end;
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39541640
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Symlink и ярлык не путаешь?
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39541717
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,

Может и путаю. А как по ярлыку узнать путь до объекта?
Желательно кроссплатформ
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39541746
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUЖелательно кроссплатформ
lnk - это виндовое изобретение.
https://msdn.microsoft.com/en-us/library/windows/desktop/bb774950(v=vs.85).aspx
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39541754
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,

А в Линуксах и Макосях чем обходятся? Есть же рабочий стол, вся фигня
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39541762
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зависит от оболочки. Про все не скажу, но в кде это как ини-файл.
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39541787
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUА в Линуксах и Макосях чем обходятся?
Чем на макоси не знаю, а на линуксе это обычный текстовый файл *.desktop соответствующий спецификации Desktop Entry .
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39541973
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOU,

IShellLink если по простому

PS: неправильно работает в ряде случаев. если нужно всегда, то только самому парсить
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39542932
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот тут есть решение от Рея Конопки . Ниже мой переделанный вариант с распознаванием реальных путей из lnk-файлов и раскрытием их с коротких имен до полных (например, используется для обработки перетаскиваемых файлов из проводника в приложение):

получаем реальный путь к файлу из ярлыка
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
function GetRealLinkFile(const AFileFullName: string): string;
var
  source: string;
  link: IShellLinkW;
  linkFile: IPersistFile;
  shortPath: array[0..MAX_PATH] of Char;
  findData: TWin32FindData;
  isNeedUninitialize: Boolean;

  function GetLongName(const AFile: string): string;
  var
    longPath: string;
    sz: Integer;
  begin
    // делает из короткого имени длинное
    // см. реализацию в IOUtils.TPath.GetTempPath
    if AFile.Contains('~') then
    begin
      sz := GetLongPathName(PChar(AFile), nil, 0);
      SetLength(longPath, sz - 1);
      GetLongPathName(PChar(AFile), PChar(longPath), sz);
      Result := longPath;
    end
    else
    begin
      Result := AFile;
    end;
  end;

  function CustomFileExists(const AFile: string): Boolean;
  begin
    if AFile.StartsWith('\\') then
    begin
      Result := TFile.Exists(source);
    end
    else
    begin
      Result := TFile.Exists('\\?\' + source);
    end;
  end;

begin
  // получает реальный путь к файлу с учетом ярлыка и преобразует короткое имя с ~ в полное
  // только для windows
  // автор jaydi85@gmail.com
  // на основе https://forums.embarcadero.com/thread.jspa?threadID=171700
  // и https://stackoverflow.com/questions/16874118/delphi-how-to-check-if-a-file-exists-path-over-255-characters
  source := GetLongName(AFileFullName);
  Result := source;

  if (AnsiLowerCase(ExtractFileExt(source)) <> '.lnk') or not CustomFileExists(source) then
  begin
    Exit;
  end;

  // инициализация COM, если код будет вызван из не основного потока или библиотеки
  isNeedUninitialize := SUCCEEDED(CoInitializeEx(nil, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE));
  try
    // ярлык грузится в ShellLink и оттуда вытаскивается адрес
    OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLinkW, link));
    try
      OleCheck(link.QueryInterface(IPersistFile, linkFile));
      try
        OleCheck(linkFile.Load(PWideChar(source), STGM_READ));
        OleCheck(link.Resolve(0, SLR_ANY_MATCH or SLR_NO_UI));
        OleCheck(link.GetPath(shortPath, MAX_PATH, findData, SLGP_SHORTPATH));

        Result := GetLongName(shortPath);
      finally
        linkFile := nil;
      end;
    finally
      link := nil;
    end;
  finally
    if isNeedUninitialize then
    begin
      CoUninitialize;
    end;
  end;
end;



P.S. Тестировалось не во всех версиях винды и не со всеми извращенными путями
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39543018
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JaDi,

Красавчик ;)
Спасибо
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39543043
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Известный баг (особенность) использования IShellLink в x64 системах - если ссылка ссылается на файл в %PROGRAM FILES%, то при использовании данного метода в 32 битном приложении метод может отдать имя из %PROGRAM FILES (x86)%. Может быть пригодится - мой код , который читает содержимое lnk файла прямым чтением структур файла.
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39543070
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aniskin,

Это огонь!
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39543075
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В линуксе всё сильно проще:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
function ExtractTarget(const ADesktopFileName : String) : String;
const

 Entry = 'desktop entry';

begin

  with TIniFile.Create(ADesktopFileName, [ifoStripQuotes]) do
   try

    case LowerCase(ReadString(Entry, 'type', '')) of

     'application' : Result := ReadString(Entry, 'exec', '');

     'link'        : begin

                      Result := ReadString(Entry, 'url', '');

                      if Pos('file://', Result) = 1 then
                       Delete(Result, 1, 7)
                      else
                       Result := '';

                     end;

    else

     Result := '';

    end;

   finally

    Free;

   end;

end;
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39543121
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давайте ещё для полноты картины код под Макось и телефоны :)
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39543122
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUAniskin,

Это огонь!с миру по нитке и наберёшь гляди
добавлю баг для этого кода: ярлык сафари попробуй прочитать
...
Рейтинг: 0 / 0
Путь до объекта по ярлыку (FileGetSymLinkTarget)
    #39543157
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kealon(Ruslan)добавлю баг для этого кода: ярлык сафари попробуй прочитатьМожешь выложить этот ярлык? Хочется глянуть на причину проблемы.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Путь до объекта по ярлыку (FileGetSymLinkTarget)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]