Символические ссылки являются мощным инструментом в работе с файловой системой, но иногда могут возникать проблемы, особенно при работе с сетью. В данной статье мы рассмотрим одну из таких проблем и пути её решения на примере использования Delphi XE5 и XE6.
Проблема с чтением символических ссылок в Delphi
При работе с программным созданием символических ссылок в Delphi XE5 и XE6, разработчики столкнулись с проблемой, когда функция FileGetSymLinkTarget возвращала false и пустую строку для ссылок, указывающих на сетевые ресурсы. Это происходило, несмотря на то, что сами ссылки работали корректно на уровне файловой системы.
Пошаговое решение
Шаг 1: Анализ проблемы
Исследование проблемы показало, что внутренняя функция InternalGetFileNameFromSymLink в модуле SysUtils.pas не может корректно обработать ссылки на сетевые ресурсы. Вызов функции GetObjectInfoName возвращал правильный путь, но затем он обнулялся функцией ExpandVolumeName, вероятно, из-за использования префикса.
Шаг 2: Поиск альтернативного решения
Разработчикам удалось найти альтернативный способ чтения целевого пути символической ссылки, используя функцию GetFinalPathNameByHandle. Этот подход позволяет корректно обрабатывать ссылки как на локальные, так и на сетевые ресурсы.
Шаг 3: Реализация функции MyFileGetSymLinkTarget
На основе примера, предоставленного Sertac, была создана функция MyFileGetSymLinkTarget, которая возвращает правильный путь для символической ссылки. Функция использует CreateFile для получения дескриптора файла, а затем GetFinalPathNameByHandle для получения целевого пути. В случае, если путь начинается с \?\UNC\, производится его корректировка.
function MyFileGetSymLinkTarget(const APathToLink: string; var ATarget: string): boolean;
var
LinkHandle: THandle;
TargetName: array[0..512] of Char;
begin
ATarget := '';
LinkHandle := CreateFile(PChar(APathToLink), 0, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
Win32Check(LinkHandle <> INVALID_HANDLE_VALUE);
try
Result := GetFinalPathNameByHandle(LinkHandle, TargetName, 512, FILE_NAME_NORMALIZED) > 0;
if Result then
begin
ATarget := TargetName;
if StartsText(ATarget, '\?\UNC\') then
Delete(ATarget, 3, 6); // Удаляем префикс \?\UNC\
else if StartsText(ATarget, '\?\') then
Delete(ATarget, 3, 4); // Удаляем префикс \?\
end;
finally
CloseHandle(LinkHandle);
end;
end;
Шаг 4: Использование функции MyFileGetSymLinkTarget
Разработчикам рекомендуется сначала использовать FileGetSymLinkTarget и только в случае, если возвращаемый путь пуст, применять MyFileGetSymLinkTarget.
Заключение
В данной статье мы рассмотрели проблему, связанную с чтением символических ссылок в Delphi XE5 и XE6, и предложили решение, которое позволяет корректно работать с ссылками на локальные и сетевые ресурсы. Важно отметить, что создание символических ссылок на сетевые ресурсы может иметь свои ограничения, и при необходимости следует учитывать рекомендации разработчиков Windows.
Техники решения проблем, связанных с корректным чтением символических ссылок в среде разработки Delphi XE5 и XE6, включая анализ неполадок и разработку альтернативной функции для обработки таких ссылок.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.