C++ 查找符号链接指向的位置(窗口)

C++ 查找符号链接指向的位置(窗口),c++,c,winapi,symlink,C++,C,Winapi,Symlink,我使用FindFirstFile()和co函数浏览C:\example\dir的内容。通过检查d.dwAttributes&file\u ATTRIBUTE\u resparse\u POINT!=0。然而,我还没有找到一种方法来跟踪链接并查看它所指向的位置。这可能吗?要找到符号链接的目标,必须打开符号链接。对象管理器取消对链接的引用,并将句柄返回到目标位置。调用该句柄将返回目标的路径名 以下实现返回给定符号链接的目标位置: std::wstring GetLinkTarget( const s

我使用FindFirstFile()和co函数浏览
C:\example\dir
的内容。通过检查
d.dwAttributes&file\u ATTRIBUTE\u resparse\u POINT!=0
。然而,我还没有找到一种方法来跟踪链接并查看它所指向的位置。这可能吗?

要找到符号链接的目标,必须打开符号链接。对象管理器取消对链接的引用,并将句柄返回到目标位置。调用该句柄将返回目标的路径名

以下实现返回给定符号链接的目标位置:

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 );
}
std::wstring GetLinkTarget(const std::wstring&a_Link){
//定义自动句柄清理的智能指针类型。
typedef std::唯一的文件句柄;
//仅打开用于查询的文件(无读/写访问权限)。
FileHandle h(::CreateFileW(a_Link.c_str(),0,
文件共享读取文件共享写入文件共享删除,
nullptr,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,nullptr),
&::闭合手柄);
if(h.get()==无效的句柄值){
h、 释放();
抛出std::runtime_错误(“CreateFileW()失败”);
}
const size\u t requiredSize=::GetFinalPathNameByHandleW(h.get(),nullptr,0,
文件名(标准化);
如果(requiredSize==0){
抛出std::runtime_错误(“GetFinalPathNameByHandleW()失败”);
}
标准::向量缓冲区(所需大小);
::GetFinalPathNameByHandleW(h.get(),buffer.data(),
静态_转换(buffer.size()),
文件名(标准化);
返回std::wstring(buffer.begin(),buffer.end()-1);
}


注意:有关基于see的RAII包装器的详细信息,请参见。

代码中有一个错误:函数末尾的文件句柄没有关闭。只有当GetFinalPathNameByHandleW()返回0时,它才会关闭。@Andy:是的。还有另一个不太明显的bug:如果
std::vector
抛出异常,文件句柄也不会关闭。这可以通过使用在
句柄上实现RAII的库来解决。我将添加适当的注释。@IInspectable:在C++11中,您可以使用
std::unique\u ptr
std::shared\u ptr
(或boost等效项)作为RAII包装器,它们都支持自定义删除器,并且
CloseHandle()
可以用于删除器。谢谢您。别担心可能的泄漏,我会处理的this@RemyLebeau我一直忘了,C++现在是一种新语言。感谢您对实施异常安全资源管理的建议。