Я использую FindFirstFile() и сопутствующие функции для просмотра содержимого C:\example\dir
. Я знаю, что чтение файла может представлять собой символическую ссылку, соединение и т. Д., Проверяя, d.dwAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0
. Тем не менее, я не нашел способ следить за ссылкой и видеть местоположение, на которое оно указывает. Возможно ли это?Поиск ссылки на символическую ссылку (Windows)
2
A
ответ
3
Чтобы найти цель символической ссылки, вам нужно открыть символическую ссылку. Диспетчер объектов разыгрывает ссылку и возвращает дескриптор в целевое местоположение. Вызов GetFinalPathNameByHandle на этом дескрипторе возвращает путь к цели.
Следующая реализация возвращает местоположение цели, учитывая символическую ссылку:
std::wstring GetLinkTarget(const std::wstring& a_Link) {
// Define smart pointer type for automatic HANDLE cleanup.
typedef std::unique_ptr<std::remove_pointer<HANDLE>::type,
decltype(&::CloseHandle)> FileHandle;
// Open file for querying only (no read/write access).
FileHandle h(::CreateFileW(a_Link.c_str(), 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr),
&::CloseHandle);
if (h.get() == INVALID_HANDLE_VALUE) {
h.release();
throw std::runtime_error("CreateFileW() failed.");
}
const size_t requiredSize = ::GetFinalPathNameByHandleW(h.get(), nullptr, 0,
FILE_NAME_NORMALIZED);
if (requiredSize == 0) {
throw std::runtime_error("GetFinalPathNameByHandleW() failed.");
}
std::vector<wchar_t> buffer(requiredSize);
::GetFinalPathNameByHandleW(h.get(), buffer.data(),
static_cast<DWORD>(buffer.size()),
FILE_NAME_NORMALIZED);
return std::wstring(buffer.begin(), buffer.end() - 1);
}
Примечание: Для получения дополнительной информации о RAII обертки на основе std::unique_ptr см std::unique_ptr, deleters and the Win32 API.
Смежные вопросы
- 1. Ограничение на символическую ссылку - Windows
- 2. Удалить символическую ссылку с PHP на Windows
- 3. Как создать символическую ссылку в Windows Vista?
- 4. Windows ярлык на символическую ссылку на исполняемый файл
- 5. Как создать символическую ссылку на Windows через Ruby?
- 6. Удалить символическую ссылку
- 7. В Windows/NTFS можно перемещать символическую ссылку на другой компьютер?
- 8. Создать символическую ссылку на программу
- 9. Как найти символические ссылки значка, указывающего на другую символическую ссылку
- 10. Метеор создает символическую ссылку на неправильный компьютер
- 11. Symfony2 создает символическую ссылку на пользовательские ресурсы
- 12. Переименовать символическую ссылку с Qt
- 13. Невозможно получить символическую ссылку на работу (windows 7) cmd
- 14. создать символическую ссылку на несколько каталогов centos
- 15. Как перемещать относительную символическую ссылку?
- 16. Заменить важную символическую ссылку «безопасно»
- 17. Обновить устаревшую символическую ссылку linux
- 18. Как заставить Git игнорировать символическую ссылку?
- 19. php не разрешает символическую ссылку
- 20. случайно создал символическую ссылку
- 21. Как перенести символическую ссылку на корзину?
- 22. Использование C#, как скопировать символическую ссылку в Windows Vista, 7,2008
- 23. символические ссылки на Windows,
- 24. Как сделать символическую ссылку с cygwin в Windows 7
- 25. Определите, имеет ли Windows-процесс право создавать символическую ссылку
- 26. Попытка сделать символическую ссылку на сценарий Powershell на удаленном сервере
- 27. Как заставить создание символической ссылки переопределить существующую символическую ссылку?
- 28. Создать символическую ссылку на файл в Perforce
- 29. File.delete() не удаляет символическую ссылку на Android?
- 30. Как создать символическую ссылку на сервере heroku?
В коде есть ошибка: дескриптор файла не закрыт в конце функции. Он только закрывается, если GetFinalPathNameByHandleW() возвращается 0. – Andy
@Andy: Это правда. Там также есть еще одна ошибка, это менее заметно: если 'std :: vector' выдает исключение, дескриптор файла также не закрывается. Это можно решить, используя библиотеку, которая реализует RAII над 'HANDLE'. Я добавлю соответствующие комментарии. – IInspectable
@IInpectable: в C++ 11 вы можете использовать 'std :: unique_ptr' или' std :: shared_ptr' (или эквиваленты форсирования) в качестве оболочки RAII, они поддерживают пользовательские удалители, а 'CloseHandle()' может используется для деэфира. –