应使用unc路径(如@"\serversharepath")替代映射驱动器,因其跨会话稳定;需启用系统长路径支持并避免path.getfullpath;凭据需通过进程身份或wnetaddconnection2设置,networkcredential对system.io无效。

如何用 System.IO 访问映射的网络驱动器(如 Z:)
能访问,但前提是当前进程运行在拥有该映射的用户上下文中。Windows 的网络驱动器映射(net use Z: \servershare)是会话级、用户级的,服务或不同用户启动的进程看不到它。
- 交互式登录用户启动的 GUI 或控制台程序——通常能直接读写
Z:ile.txt - Windows 服务、计划任务(配置为“不使用用户会话”)、或以其他用户身份启动的进程——
Directory.Exists("Z:\")返回false,File.OpenRead抛UnauthorizedAccessException或DirectoryNotFoundException - 不要依赖
DriveInfo.GetDrives()判断映射是否“存在”,它只反映当前会话可见的驱动器
绕过映射、直连 UNC 路径的正确写法
UNC(\serversharepath)才是稳定可跨会话使用的路径格式。但直接拼接字符串容易出错,尤其涉及权限和反斜杠转义。
- 始终用正斜杠或双反斜杠:
@"\servershareolder"或"\\server\share\folder",避免单反斜杠触发转义(如"s"变成响铃字符) - UNC 路径不支持
Path.GetFullPath(),会抛ArgumentException;改用Path.Combine("\\server\share", "sub", "file.txt")安全拼接 - 若需验证路径可达,别用
File.Exists()先查——它对 UNC 可能超时或静默失败;改用new DirectoryInfo(@"\servershare").Exists更可靠
处理凭据:为什么 NetworkCredential 在 File.Copy 里不起作用
System.IO 所有 API(包括 File.Copy、Directory.GetFiles)底层走 Windows I/O 子系统,不接受显式凭据参数。它们只能用当前进程令牌里的身份访问网络资源。
- 想用指定账号访问 UNC?必须让进程本身以该账号运行(如用
runas /user:DOMAINuser cmd启动),或调用 Win32WNetAddConnection2在当前会话中临时建立带凭据的连接 -
NetworkCredential只在WebClient、HttpClient、SmtpClient等网络类里生效,跟文件系统无关 - 常见错误:写
File.Copy(src, @"\other-serversharedest", true)时 src 是本地路径、dest 是 UNC,结果因 dest 权限失败——错误不在 copy 函数,而在目标共享未授权当前用户写入
长路径与符号链接:访问 >260 字符 UNC 路径的硬要求
Windows 默认限制路径长度为 260 字符(MAX_PATH),而深层嵌套的 UNC 路径(如 \servershareolder...ile.txt)极易突破。不处理会直接报 PathTooLongException 或 DirectoryNotFoundException。
- 启用长路径支持是系统级开关:需在注册表设
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlFileSystem@LongPathsEnabled = 1,且 .NET Core 3.0+ / .NET 5+ 才默认识别 - .NET Framework 4.6.2+ 需额外在 app.config 中开启:
<appcontextswitchoverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false"></appcontextswitchoverrides> - 即使开了长路径,
\?UNCservershare这种前缀格式仍不被System.IO原生支持——它只认标准 UNC;真正有效的仍是启用系统开关 + 用普通\servershare写法
网络路径的权限模型、会话隔离、长路径限制这三块,任一没对齐都会让代码在开发机跑通、上线就挂。尤其是服务场景下,别信“它之前好好的”,先确认进程身份和映射归属。










