如何在.NET Core中设置凭据连接远程计算机并复制文件?
在.NET Core中带凭据访问远程共享并复制文件
直接用File.Copy访问远程路径时,系统会默认使用当前进程的身份去访问,所以如果远程共享需要特定权限,就会出现Access to path is denied的错误。我之前也碰到过这个问题,解决思路是先通过Windows原生网络API建立带凭据的远程连接,之后再执行文件复制操作。
实现步骤:
- 导入Windows原生网络API:我们需要用到
WNetAddConnection2来建立带凭据的连接,以及WNetCancelConnection2来断开连接(可选操作)。 - 定义必要的结构体:这些结构体是API调用所需的参数载体。
- 建立带凭据的远程连接:传入远程共享路径、用户名、密码。
- 执行文件复制:连接建立后,就可以正常使用
File.Copy完成操作。 - (可选)断开连接:如果不需要长期保持远程连接,可以在操作完成后主动断开。
完整代码示例
using System; using System.IO; using System.Runtime.InteropServices; public class RemoteFileCopier { // 导入Windows网络连接相关API [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int WNetAddConnection2(ref 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 struct NETRESOURCE { public int dwScope; public int dwType; public int dwDisplayType; public int dwUsage; public string lpLocalName; public string lpRemoteName; public string lpComment; public string lpProvider; } // 建立远程共享连接的方法 private static void ConnectToRemote(string remotePath, string username, string password) { var netResource = new NETRESOURCE { dwType = 0x00000001, // 指定为磁盘资源类型 lpRemoteName = remotePath }; int result = WNetAddConnection2(ref netResource, password, username, 0); if (result != 0) { throw new System.ComponentModel.Win32Exception(result); } } // 断开远程共享连接的方法 private static void DisconnectFromRemote(string remotePath) { int result = WNetCancelConnection2(remotePath, 0, true); if (result != 0) { throw new System.ComponentModel.Win32Exception(result); } } public static void CopyFileToRemote(string sourcePath, string destRemotePath, string remoteUsername, string remotePassword) { // 提取远程共享根路径(比如从\\server\share\file.txt中提取\\server\share) string remoteSharePath = Path.GetPathRoot(destRemotePath).TrimEnd(Path.DirectorySeparatorChar); try { // 先建立远程连接 ConnectToRemote(remoteSharePath, remoteUsername, remotePassword); // 执行文件复制 File.Copy(sourcePath, destRemotePath, true); Console.WriteLine("文件复制成功!"); } catch (Exception ex) { Console.WriteLine($"操作失败:{ex.Message}"); throw; } finally { // 可选:如果不需要保持连接,这里断开;如果后续还有操作可以注释此行 DisconnectFromRemote(remoteSharePath); } } // 示例调用 public static void Main() { string source = @"C:\local\test.txt"; string dest = @"\\RemotePC\SharedFolder\test.txt"; string username = @"RemotePC\AdminUser"; // 格式:机器名\用户名 或 域名\用户名 string password = "YourSecurePassword"; CopyFileToRemote(source, dest, username, password); } }
注意事项:
- 用户名格式:如果是远程机器的本地账户,用
REMOTE_MACHINE_NAME\Username;如果是域账户,用DOMAIN_NAME\Username。 - 平台限制:这个方案依赖Windows的
mpr.dll,所以仅适用于Windows平台的.NET Core应用。如果是跨平台场景,可以考虑使用第三方SMB客户端库(比如SMBLibrary)来实现。 - 错误排查:API调用返回的错误码可以通过
Win32Exception获取详细信息,方便定位连接失败的原因。 - 连接复用:如果需要多次操作同一远程共享,可以只建立一次连接,所有操作完成后再断开,减少重复连接的开销。
内容的提问来源于stack exchange,提问作者shani klein
相关产品推荐
相关产品推荐

