使用C#/WindowsForms实现带Windows认证的网络加密文件夹复制求助
实现带Windows凭据验证的网络文件夹复制功能
下面是一套完整的实现思路和代码示例,适合编程经验有限的开发者快速集成:
1. 检测共享文件夹是否需要认证
核心逻辑是尝试访问目标共享目录,如果触发UnauthorizedAccessException,就说明需要用户名密码验证。
private bool IsShareRequiresCredentials(string networkPath) { try { // 尝试读取共享目录的文件列表(仅做权限检测,不实际读取内容) Directory.GetFiles(networkPath); return false; } catch (UnauthorizedAccessException) { return true; } catch (Exception ex) { // 处理其他异常(比如路径不存在、网络不通等) MessageBox.Show($"访问共享出错:{ex.Message}"); return false; } }
2. 弹出凭据输入窗口
用Windows Forms自定义一个简单的输入窗口(比系统自带的InputBox更灵活):
自定义凭据输入Form
在项目中新建一个Windows Form(命名为CredentialForm),添加:
- 两个Label:显示"用户名:"、"密码:"
- 两个TextBox:
txtUsername(输入用户名)、txtPassword(输入密码,将PasswordChar设为*) - 两个Button:"确认"、"取消"
然后在Form类里添加以下代码暴露输入的凭据:
public string Username { get; private set; } public string Password { get; private set; } private void btnConfirm_Click(object sender, EventArgs e) { Username = txtUsername.Text.Trim(); Password = txtPassword.Text; DialogResult = DialogResult.OK; Close(); } private void btnCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Close(); }
调用方式:
using (var credentialForm = new CredentialForm()) { if (credentialForm.ShowDialog() == DialogResult.OK) { string username = credentialForm.Username; string password = credentialForm.Password; // 用获取到的凭据访问共享 } }
3. 使用凭据挂载共享并复制文件
需要调用Windows系统API WNetAddConnection2来挂载共享并传入凭据,完成复制后记得卸载共享避免残留。
先声明API和相关结构体
using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] 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; } [DllImport("mpr.dll")] private static extern int WNetAddConnection2(ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags); [DllImport("mpr.dll")] private static extern int WNetCancelConnection2(string lpName, int dwFlags, bool fForce);
挂载共享+复制文件的方法
private bool CopyNetworkFolder(string networkPath, string localPath, string username, string password) { NETRESOURCE nr = new NETRESOURCE(); nr.dwType = 0x00000001; // 资源类型为磁盘 nr.lpRemoteName = networkPath; // 挂载共享 int result = WNetAddConnection2(ref nr, password, username, 0); if (result != 0) { MessageBox.Show($"凭据错误或共享无法访问,错误码:{result}"); return false; } try { // 递归复制文件夹(包含子目录和文件) CopyDirectory(networkPath, localPath); MessageBox.Show("复制完成"); return true; } catch (Exception ex) { MessageBox.Show($"复制出错:{ex.Message}"); return false; } finally { // 卸载共享,避免占用资源 WNetCancelConnection2(networkPath, 0, true); } } // 递归复制文件夹的辅助方法 private void CopyDirectory(string sourceDir, string destDir) { // 创建目标目录 Directory.CreateDirectory(destDir); // 复制文件 foreach (string file in Directory.GetFiles(sourceDir)) { string destFile = Path.Combine(destDir, Path.GetFileName(file)); File.Copy(file, destFile, true); // true表示覆盖已存在的文件 } // 递归复制子目录 foreach (string subDir in Directory.GetDirectories(sourceDir)) { string destSubDir = Path.Combine(destDir, Path.GetFileName(subDir)); CopyDirectory(subDir, destSubDir); } }
4. 整合所有逻辑的主调用示例
private void btnStartCopy_Click(object sender, EventArgs e) { string networkPath = @"\\server\sharedFolder"; // 替换为你的网络共享路径 string localPath = @"C:\LocalCopy"; // 本地目标路径 if (IsShareRequiresCredentials(networkPath)) { using (var credentialForm = new CredentialForm()) { if (credentialForm.ShowDialog() == DialogResult.OK) { CopyNetworkFolder(networkPath, localPath, credentialForm.Username, credentialForm.Password); } } } else { // 无需凭据,直接复制 CopyDirectory(networkPath, localPath); MessageBox.Show("复制完成"); } }
注意事项
- 确保项目引用了
System.Windows.Forms和System.IO - 网络路径格式必须是
\\服务器名\共享文件夹名 WNetAddConnection2返回0表示成功,其他错误码可查Windows官方文档排查(比如1326表示用户名或密码错误)
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

