如何在C#中传递网络凭据?手动输入凭据问题求助
网络凭据自动验证问题求助
我写的文件传输函数必须手动打开源和目标文件夹并输入网络凭据才能正常运行。本来以为用NetworkCredential能解决自动验证的问题,但试了之后没用,还是得手动输凭据,求各位帮忙解决,谢谢!

public bool TransferSingle(int id) { // Ahron single PC var ahron = _ahronRepository.GetAhronById(id); try { // Return isOK status if everything is ok bool isOk; // Get Ahron Credentials var credentials = _ahronRepository.GetAhronCred(1); var username = Decrypt(credentials.User); var pwd = Decrypt(credentials.Pwd); if (ahron != null) { var status = Ping(ahron.Hostname); var fullDestinationPath = ahron.DestinationPath + @"\\" + ahron.Line; if (status) { // If host is alive ChangeStatus(ahron.Id, true); // Network Credentials NetworkCredential theNetworkCredential = new NetworkCredential(username, pwd); CredentialCache theNetCache = new CredentialCache(); theNetCache.Add(new Uri(@"\\\\" + ahron.Sourcepath), "Basic", theNetworkCredential); theNetCache.Add(new Uri(@"\\\\" + ahron.DestinationPath), "Basic", theNetworkCredential); if (!Directory.Exists(fullDestinationPath)) { Directory.CreateDirectory(fullDestinationPath); } if (!Directory.Exists(ahron.Sourcepath.Trim())) { Directory.CreateDirectory(ahron.Sourcepath); } int numberOfTotalFiles = 0; foreach (var file in new DirectoryInfo(ahron.Sourcepath.Trim()).GetFiles()) { var filePath = fullDestinationPath + file.Name; if (File.Exists(filePath)) { File.Delete(file.FullName); } else { file.MoveTo($@"{fullDestinationPath}\\{file.Name}"); numberOfTotalFiles++; } } // Total number of files UpdateLastTransfer(ahron.Id, numberOfTotalFiles); isOk = true; } else { isOk = false; ChangeStatus(ahron.Id, false); CreateAhronLog(ahron.Hostname, "Hostname was offline"); } } else { isOk = false; } return isOk; } catch (Exception ex) { _logceService.Create("Critical", $"Ahron Credentials - {ex.Message}", DateTime.Now); if (ahron != null) { CreateAhronLog(ahron.Hostname, ex.Message); } else { CreateAhronLog("Anonymous", ex.Message); } return false; } }
问题原因及解决办法
- Uri格式与协议错误:你用
\\\\\\拼接路径会导致格式错误,且网络共享不使用"Basic"验证协议,应该用NTLM/Kerberos。另外CredentialCache是给Web请求用的,Directory/File类不会自动读取其中的凭据。 - 正确方式:调用Windows API建立网络连接:要访问网络共享,需要通过系统API预先建立带凭据的连接,而非依赖
NetworkCredential缓存。
关键修改代码
首先在类中添加Windows API调用声明:
[DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int WNetAddConnection2( NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private class NETRESOURCE { public int dwScope = 0; public int dwType = 1; // 磁盘资源类型 public int dwDisplayType = 0; public int dwUsage = 0; public string lpLocalName = ""; public string lpRemoteName; public string lpComment = ""; public string lpProvider = ""; }
然后替换原代码中NetworkCredential相关的部分,改为建立网络连接:
// 建立源路径的网络连接 var sourceResource = new NETRESOURCE { lpRemoteName = ahron.Sourcepath }; int sourceResult = WNetAddConnection2(sourceResource, pwd, username, 0); // 1219是已存在相同连接的错误码,可忽略 if (sourceResult != 0 && sourceResult != 1219) { throw new Exception($"连接源路径失败,错误码:{sourceResult}"); } // 建立目标路径的网络连接 var destResource = new NETRESOURCE { lpRemoteName = ahron.DestinationPath }; int destResult = WNetAddConnection2(destResource, pwd, username, 0); if (destResult != 0 && destResult != 1219) { throw new Exception($"连接目标路径失败,错误码:{destResult}"); }
额外注意
- 操作完成后可调用
WNetCancelConnection2断开连接,避免残留无效连接。 - 用户名如果是域账号,需用
域\用户名的格式。 - 可根据返回的错误码排查问题(比如错误码5=权限不足,1326=账号密码错误)。
内容的提问来源于stack exchange,提问作者Maria
相关产品推荐
相关产品推荐

