使用C#访问SMB共享时出现“找不到网络名称”错误
解决C#访问SMB共享时Error 67(网络名称无法找到)问题
常见排查与修复步骤
1. 验证共享路径格式
- 去掉路径末尾多余的反斜杠:你的代码中路径
@"\\192.168.1.89\Main-Storage\"末尾的\可能导致解析错误,改为@"\\192.168.1.89\Main-Storage"再尝试。 - 手动在文件资源管理器中输入该UNC路径,确认能正常访问,排除网络或共享本身的配置问题。
2. 检查smbconn类的API调用逻辑
你使用的smbconn是自定义类,核心是它是否正确调用Windows API(如WNetAddConnection2)建立连接,常见错误点:
- 确保
NETRESOURCE结构体参数正确:dwType设为RESOURCETYPE_DISK,lpRemoteName传入不带末尾反斜杠的共享路径,lpLocalName留空(无需映射驱动器)。 - 检查API调用的返回值,不要忽略潜在错误,比如凭证是否正确传递、用户是否有共享访问权限。
3. 处理现有连接冲突
如果之前已通过其他凭证或方式连接过该共享,会导致新连接失败:
- 先调用
WNetCancelConnection2断开现有连接,再重新建立:// 强制断开指定共享连接(需调用Windows API) WNetCancelConnection2(@"\\192.168.1.89\Main-Storage", 0, true); - 若共享已映射为驱动器号,断开时需指定驱动器号或UNC路径,强制断开(第三个参数设为
true)。
4. 权限与环境排查
- 确认程序运行的进程权限:如果是Windows服务,默认可能无网络访问权限,需将服务登录账户设为有权访问共享的用户。
- 检查防火墙:确保本地和远程主机的防火墙允许SMB通信(默认端口445)。
- 使用完整的用户名格式:比如
@"COMPUTERNAME\user"或@"DOMAIN\user",避免凭证解析错误。
修正后的标准API实现示例
如果smbconn类存在逻辑问题,可以替换为直接调用Windows API的实现:
using System; using System.Runtime.InteropServices; using System.Security; using System.Windows.Forms; public class SmbConnection : IDisposable { private readonly string _remotePath; [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int WNetAddConnection2([In] NETRESOURCE lpNetResource, string lpPassword, string lpUserName, int dwFlags); [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int WNetCancelConnection2(string lpName, int dwFlags, bool fForce); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private class NETRESOURCE { public int dwScope = 0; public int dwType = 1; // RESOURCETYPE_DISK public int dwDisplayType = 0; public int dwUsage = 0; public string lpLocalName = ""; public string lpRemoteName; public string lpComment = ""; public string lpProvider = ""; } public SmbConnection(string remotePath, NetworkCredential credentials) { _remotePath = remotePath.TrimEnd('\\'); var nr = new NETRESOURCE { lpRemoteName = _remotePath }; int result = WNetAddConnection2(nr, credentials.Password, credentials.UserName, 0); if (result != 0) { throw new System.ComponentModel.Win32Exception(result); } } public void Dispose() { WNetCancelConnection2(_remotePath, 0, true); } } // 使用示例 NetworkCredential credentials = new NetworkCredential("user", "pass"); try { using (new SmbConnection(@"\\192.168.1.89\Main-Storage", credentials)) { var files = Directory.GetFiles(@"\\192.168.1.89\Main-Storage"); MessageBox.Show(string.Join(Environment.NewLine, files)); } } catch (Exception ex) { MessageBox.Show($"错误信息: {ex.Message}"); }
最终验证
- 运行修正后的代码,捕获并查看具体异常信息(若仍有错误)。
- 确认远程共享的共享权限和NTFS权限都允许指定用户访问。
- 跨域或工作组环境下,确保远程主机的用户账户已启用网络访问权限。
内容的提问来源于stack exchange,提问作者CSAPawn
相关产品推荐
相关产品推荐

