Windows 10
MS VS 2015
C 11
提升1.60
我创建此符号链接:
mklink /J "C:T4 2.0ApplicationSymlinksT4" "C:T4 2.0Data"
这是程序的简化版本,用于检查符号链接是否链接到适当目录:
#include <boost/filesystem.hpp>
#include <iostream>
int main()
{
boost::filesystem::path directory = "c:\T4 2.0\Data";
boost::filesystem::path symlink = "c:\T4 2.0\ApplicationSymlinks\T4";
boost::filesystem::path path_linked_to("");
path_linked_to = boost::filesystem::read_symlink(symlink); // Resolve symlink. path_linked_to is not absolute. L"\T4 2.0\Data"
path_linked_to = boost::filesystem::absolute(path_linked_to); // Absolute path. L"c:\T4 2.0\Data"
if (directory == path_linked_to)
std::cout << "paths are equal" << std::endl;
else
std::cout << "paths are not equal" << std::endl;
return 0;
}
输出是"路径不相等"。他们不应该平等吗?在调试器的汽车窗口中,我确实看到了:
directory size 14 capacity 15
其中
path_linked_to size 16 capacity 23 because it includes two trailing ' 's.
read_symlink
中引入了这两个尾声' '
S。
如何解决这个问题?read_symlink
为什么不返回绝对?read_symlink
为什么添加两个尾随' '
S(假设这是问题)?operator==
为什么不忽略' '
S?
我如何编译和链接:
C:Program Files (x86)Microsoft Visual Studio 14.0VCbinx86_amd64CL.exe /c /IC:Librariesboost_1_60_0 /ZI /nologo /W3 /WX- /sdl /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"x64Debug\" /Fd"x64Debugvc140.pdb" /Gd /TP /errorReport:prompt resolvesymlilnk.cpp stdafx.cpp
C:Program Files (x86)Microsoft Visual Studio 14.0VCbinx86_amd64link.exe /ERRORREPORT:PROMPT /OUT:"c:UsersThereforeDocumentsVisual Studio 2015Projectsresolvesymlilnkx64Debugresolvesymlilnk.exe" /INCREMENTAL /NOLOGO /LIBPATH:"C:Librariesboost_1_60_0lib64-msvc-14.0" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /Debug /PDB:"c:UsersThereforeDocumentsVisual Studio 2015Projectsresolvesymlilnkx64Debugresolvesymlilnk.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"c:UsersThereforeDocumentsVisual Studio 2015Projectsresolvesymlilnkx64Debugresolvesymlilnk.lib" /MACHINE:X64 x64Debugresolvesymlilnk.obj
这是BOOST中的一个已知错误:https://svn.boost.org/trac/boost/ticket/ticket/10900
不幸的是,它尚未修复,并且被分配了低优先级,因此,如果您愿意修复它,则必须自己做。
问题在于,当boost.filesystem读取REPARSE_DATA_BUFFER
结构时,它假设reparse是符号链接,因此始终使用SymbolicLinkReparseBuffer
联合成员;对于连接点,应使用MountPointReparseBuffer
。这意味着缓冲区计算是sizeof(ULONG)
关闭的,因此读取路径缺少驱动器字母和结肠(L"C:"
),而末尾添加了两个宽字符,而您通常观察到的通常为空字符。(宽字符在离开Boost.Filesystem内部的路上转换为狭窄字符。)
修复程序将在read_symlink
中检查ReparseTag
成员是IO_REPARSE_TAG_SYMLINK
还是IO_REPARSE_TAG_MOUNT_POINT
(如is_reparse_point_a_symlink
中),并分别使用SymbolicLinkReparseBuffer
或MountPointReparseBuffer
。正如上面链接的票面所述,Boost应该真正使用SubstituteNameOffset
/SubstituteNameLength
代替PrintNameOffset
/PrintNameLength
,并剥离主要Symlink和交界处的领先L"??"
。