windows下c#访问局域网共享需用unc路径(如@"\servershare"),注意权限、凭据继承、smb版本、文件锁及路径解析五要素,避免directorynotfoundexception等错误。

用 DirectoryInfo 和 FileInfo 直接访问共享路径,但必须带 UNC 前缀
Windows 下 C# 访问局域网共享文件夹,最直接的方式就是把共享路径当成本地路径用——前提是路径格式正确。你不能写 C:share,也不能写 \servershare(缺协议头),得写成 \\server\share 或更稳妥的 \server\share(C# 字符串里反斜杠要转义,实际代码中写两个)。
常见错误现象:DirectoryNotFoundException 或 UnauthorizedAccessException,多数是因为路径拼错、权限没配或当前进程没继承登录凭据。
- 确保路径以
\\开头,比如new DirectoryInfo(@"\fileserverpublic") - 不要尝试用
DriveInfo查共享盘符——它只管本地物理/映射驱动器,对纯 UNC 无效 - 如果程序是 Windows 服务,默认运行在 LocalSystem 账户下,它看不到用户登录态的网络凭据,基本必失败
- 控制台或 WPF 应用跑在当前用户上下文时,只要该用户有共享访问权限,通常能直接通
需要显式认证?用 WNetAddConnection2 挂载临时连接
当目标共享要求特定用户名密码,而当前 Windows 登录账户没权限时,DirectoryInfo 会直接报错。这时得靠 Windows API 主动“连过去”,本质是模拟一次网络驱动器映射(不真占盘符)。
核心是调用 WNetAddConnection2,传入服务器地址、用户名、密码和空盘符(表示不映射为驱动器)。成功后,后续所有对该共享的 .NET IO 操作就自动带上这个凭据上下文。
- 必须引用
System.Runtime.InteropServices - 调用后记得用
WNetCancelConnection2清理,否则连接残留可能影响下次操作 - 密码明文传入有风险,生产环境建议用
CredentialCache或 Windows 凭据管理器配合 - 注意:.NET Core/.NET 5+ 在非 Windows 平台无法调用此 API,纯跨平台场景得换方案
File.Copy 或 FileStream 写共享目录时卡住或报错 IOException
不是代码写错了,大概率是共享本身设置了“脱机文件”或启用了 SMB 签名强制策略,导致大文件传输中途断连,或者服务器端限制了单次请求大小。
典型表现:小文件正常,几百 MB 以上复制到一半抛 IOException: The specified network name is no longer available;或者读取流时 Read 返回值突然变 0,但没到 EOF。
- 加异常重试逻辑,尤其是针对
IOException和UnauthorizedAccessException - 避免用
File.Copy处理大文件,改用分块FileStream+ 缓冲区(如 64KB),并手动控制Flush()频率 - 检查服务器 SMB 版本:Windows Server 2016+ 默认启用 SMB 3.1.1 加密,老客户端(如 .NET Framework 4.6.1 以下)可能握手失败
- 确认共享权限(Share Permissions)和 NTFS 权限(Security tab)都放开了写入,二者是“与”关系,缺一不可
为什么有时候明明能列目录,却读不了某个文件?
因为共享目录的“列出内容”权限和“读取”权限是分开控制的。NTFS 层面可能给文件单独设了拒绝(Deny)ACE,或者文件被其他进程独占打开(比如 Excel 正在编辑中)。
更隐蔽的情况:共享路径下存在符号链接(symlink)或挂载点(mount point),而当前账户没权限遍历目标路径,DirectoryInfo.GetFiles() 就会静默跳过或抛异常。
- 用
GetAccessControl()检查具体文件的FileSystemAccessRule,别只看父目录 - 尝试用
Process Explorer查看文件是否被占用,尤其注意 Office、PDF 阅读器这类常驻后台锁文件的程序 - UNC 路径下慎用
Path.GetFullPath(),它可能把\servershare..other归一化成非法路径,触发访问拒绝 - 如果涉及中文路径,确认服务器 SMB 设置没禁用 UTF-8 文件名支持(SMB 1.0 默认不支持,容易乱码导致找不到文件)
权限、凭据、SMB 协议版本、文件锁、路径解析——这五个点串起来,基本覆盖了 90% 的共享访问失败原因。调试时别一上来就查代码逻辑,先 telnet 通端口,再用资源管理器手工走一遍路径,比瞎改代码快得多。










