2
我使用FindFirstFile()和協同函數來瀏覽C:\example\dir
的內容。我知道一個文件讀取可以通過檢查是否爲d.dwAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0
來作爲符號鏈接,連接點等。但是,我還沒有找到一種方法來跟蹤鏈接並查看它指向的位置。這甚至有可能嗎?查找符號鏈接指向的位置(Windows)
我使用FindFirstFile()和協同函數來瀏覽C:\example\dir
的內容。我知道一個文件讀取可以通過檢查是否爲d.dwAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0
來作爲符號鏈接,連接點等。但是,我還沒有找到一種方法來跟蹤鏈接並查看它指向的位置。這甚至有可能嗎?查找符號鏈接指向的位置(Windows)
要找到符號鏈接的目標,您必須打開符號鏈接。對象管理器取消引用鏈接並將句柄返回到目標位置。在該句柄上調用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);
}
代碼中存在一個錯誤:文件句柄在函數結束時未關閉。它只在GetFinalPathNameByHandleW()返回0時關閉。 – Andy
@Andy:的確如此。還有另一個bug,這是不太明顯的:如果'std :: vector'拋出一個異常,那麼文件句柄也不會被關閉。這可以通過使用通過'HANDLE'實現RAII的庫來解決。我會添加適當的評論。 – IInspectable
@IInspectable:在C++ 11中,你可以使用'std :: unique_ptr'或'std :: shared_ptr'(或等價的boost)作爲RAII包裝器,它們都支持定製的刪除器,'CloseHandle()'可以用於刪除者。 –