如何在C#访问远程Access数据库前自动完成Windows用户认证?
这个问题本质上是Windows SMB共享的身份验证会话缓存失效导致的。P2重启后,P1之前和P2建立的共享访问会话被清空了,你的C#程序默认不会自动提交P2的用户凭证,所以必须手动通过网络访问触发一次身份验证,才能让系统缓存凭证供程序使用。下面给你几个实用的解决方案:
方案1:让C#程序预建立共享连接(最直接的程序级解决)
你可以在程序访问数据库之前,先调用Windows API手动建立到\\P2\F2的网络连接并传入凭证,这样程序就能自动使用这个会话访问数据库,不用手动操作。
比如用WNetAddConnection2 Win32 API实现(需要引入相关命名空间):
using System; using System.Runtime.InteropServices; public class NetworkConnection { [DllImport("mpr.dll")] private static extern int WNetAddConnection2( ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags); [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; } public static void ConnectToSharedFolder(string remotePath, string username, string password) { NETRESOURCE nr = new NETRESOURCE(); nr.dwType = 0x00000001; // RESOURCETYPE_DISK nr.lpRemoteName = remotePath; int result = WNetAddConnection2(ref nr, password, username, 0); if (result != 0) { throw new Exception($"无法建立共享连接,错误码: {result}"); } } }
在你的数据库访问代码之前调用这个方法:
NetworkConnection.ConnectToSharedFolder(@"\\P2\F2", "usr", "pwd"); // 然后执行数据库连接操作
注意:程序退出时可以调用WNetCancelConnection2断开连接,避免留下无效会话。
方案2:配置P1和P2的同名同密码账号(最省心的环境级解决)
因为你们在同一工作组,Windows访问共享时默认会用当前登录P1的用户凭证去尝试访问P2。如果P1上登录的用户账号(比如P1\localusr)和P2上的usr账号同名且密码完全一致,那么P2重启后,P1的程序访问共享时会自动匹配凭证,不需要手动输入密码。
这个方法不需要修改任何代码,只需要调整两台电脑的用户账号设置,适合长期稳定使用的场景。
方案3:在P1上保存共享凭证到Windows凭据管理器
打开P1的「控制面板」→「凭据管理器」→「Windows凭据」,点击「添加Windows凭据」:
- 输入Internet或网络地址:
\\P2 - 输入用户名:
P2\usr(或者直接usr,工作组环境下通常也能识别) - 输入密码:你的pwd
保存后,Windows会自动缓存这个凭证,P2重启后,无论是手动访问共享还是程序访问,系统都会自动使用保存的凭证进行身份验证,不用再手动登录。
为什么会出现这个问题?
简单来说,P2重启后,之前P1与P2之间建立的SMB共享会话被彻底销毁了。默认情况下,C#程序访问共享资源时,不会主动弹出凭证输入框或自动提交之前的凭证,必须通过手动访问共享的方式触发系统的凭证缓存机制,或者通过上述方法让系统/程序自动处理身份验证流程。
内容的提问来源于stack exchange,提问作者Safdar Zaman

