Junction Point是NTFS特有、仅指向本地存在的绝对路径目录的重解析点,不支持跨卷/文件/相对路径;而Symbolic Link支持文件/目录、跨卷、相对路径,但需管理员权限且兼容性较差。

什么是Junction Point,和Symbolic Link有什么区别
Windows 的 Junction Point 是一种 NTFS 文件系统特性,仅支持指向**本地目录**,且目标必须存在、必须是绝对路径(如 C:TargetDir)。它不支持跨卷、不支持相对路径、不支持文件,也不支持远程路径。与 symbolic link 不同:CreateSymbolicLink 在 Vista+ 可链接文件/目录、支持相对路径、可跨卷(需管理员权限),但 junction 更轻量、兼容性更好(XP SP2+ 即支持),且被旧版工具(如 mklink /j)和部分部署脚本依赖。
用C#调用CreateHardLink或CreateSymbolicLink?不行,得用CreateJunction
CreateHardLink 只支持文件,CreateSymbolicLink 默认创建的是 symbolic link(不是 junction),即使对目录调用,也**不会生成 NTFS junction**。真正创建 junction 必须使用 Windows API 的 DeviceIoControl 向 \.NTFS 发送 FSCTL_CREATE_OR_GET_OBJECT_ID 类似控制码?错——实际是通过 FSCTL_SET_REPARSE_POINT 写入特定格式的 REPARSE_DATA_BUFFER,其中 ReparseTag 设为 IO_REPARSE_TAG_MOUNT_POINT(0xA0000003),且数据区需按 junction 格式填充:2 字节子路径偏移 + 2 字节子路径长度 + Unicode 子路径字符串(不含驱动器号,但需以 ??C:Target 形式编码)。
实操建议:
- 别手写
REPARSE_DATA_BUFFER—— 容易字节对齐出错、Unicode 长度算错、路径前缀漏掉?? - 优先用已验证的封装库,例如 JunctionLink(MIT 开源,仅一个 .cs 文件)
- 若必须原生调用,确保进程以管理员权限运行,否则
ERROR_PRIVILEGE_NOT_HELD (1314)或ERROR_ACCESS_DENIED
用JunctionLink库创建Junction Point的最小可行代码
安装 NuGet 包:JunctionLink(注意不是 Junction 或 HardLink 等相似名)。
关键调用示例:
using JunctionLink;
<p>// 创建 junction:D:MyJunc → C:RealFolder
bool success = Junction.Create(@"D:MyJunc", @"C:RealFolder");
if (!success) {
Console.WriteLine($"创建失败,LastError: {Marshal.GetLastWin32Error()}");
}
注意事项:
- 目标目录
C:RealFolder**必须已存在**,否则失败(ERROR_PATH_NOT_FOUND) - 链接路径
D:MyJunc**必须不存在**,否则报ERROR_ALREADY_EXISTS - 路径必须是绝对路径;相对路径、UNC 路径、带通配符路径均不被接受
- 该库内部会自动处理
??前缀、Unicode 字节序、结构体对齐,比手写 P/Invoke 稳定得多
验证Junction是否成功 & 常见错误排查
创建后不要只看目录图标——资源管理器有时显示不准。可靠验证方式:
- 命令行执行:
dir /AL,junction 会显示为<JUNCTION> - 用
fsutil reparsepoint query "D:MyJunc",输出中应含Tag Value : 0xa0000003 (IO_REPARSE_TAG_MOUNT_POINT) - 在 C# 中用
File.GetAttributes(path)检查是否含FileAttributes.ReparsePoint
典型失败原因:
- 权限不足:未以管理员身份运行,或 UAC 关闭但令牌无 SeCreateSymbolicLinkPrivilege(junction 不需要此权限,但某些旧版封装误判)
- 目标路径有尾部反斜杠:
C:RealFolder→ 应传C:RealFolder(JunctionLink 会 trim,但低层 API 敏感) - 目标是符号链接或另一 junction:NTFS junction 不允许嵌套指向另一个重解析点
- 目标在压缩/加密卷上:一般不影响,但若目标启用了“不允许索引此驱动器”且父目录属性异常,偶发
ERROR_INVALID_PARAMETER
junction 的底层机制决定了它不像普通目录那样“透明”——比如某些备份工具或 IDE 文件监听器可能跳过或误判它,这点在自动化部署时容易被忽略。










