C# WNetAddConnection2重新连接在随后的尝试中失败,出现错误1312

C# WNetAddConnection2重新连接在随后的尝试中失败,出现错误1312,c#,service,windows-7,samba,C#,Service,Windows 7,Samba,背景 我有一个在windows 7(64位专业版)客户端上运行的服务,它定期检查服务器的更新,如果没有新文件,它会检查新文件以复制到本地。按照我的设置方式,服务器上的每个文件都由一个对象表示,该对象被视为与其余文件完全不同的实体 由于文件可能来自具有不同凭据的不同位置,因此每个文件都作为自己的事务处理。连接已打开,文件已传输,连接已关闭。每次更新都会处理数百个文件,不会出现问题 直到在第一次更新之后运行另一次更新(在前一次更新完成后的几分钟内),问题才会发生。发生这种情况时,第一次尝试连接到远程

背景

我有一个在windows 7(64位专业版)客户端上运行的服务,它定期检查服务器的更新,如果没有新文件,它会检查新文件以复制到本地。按照我的设置方式,服务器上的每个文件都由一个对象表示,该对象被视为与其余文件完全不同的实体

由于文件可能来自具有不同凭据的不同位置,因此每个文件都作为自己的事务处理。连接已打开,文件已传输,连接已关闭。每次更新都会处理数百个文件,不会出现问题

直到在第一次更新之后运行另一次更新(在前一次更新完成后的几分钟内),问题才会发生。发生这种情况时,第一次尝试连接到远程资源时出错,错误为1312。服务会在30秒后自动重试,直到获得良好的连接,这需要几分钟的时间,但在这段时间之后,它会通过并完成,不会再次出现问题

我尝试过使用WNetAddConnection2和WNetUseConnection,但结果相同,我使用WNetCancelConnection2关闭连接

所有这些都发生在BackgroundWorker线程中(可能在下一个线程开始之前没有被清理掉?)

定义

[DllImport( "Mpr.dll" )]
private static extern int WNetUseConnection( IntPtr hwndOwner, NETRESOURCE lpNetResource, string lpPassword, string lpUserID, int dwFlags, string lpAccessName, string lpBufferSize, string lpResult );

[DllImport( "Mpr.dll" )]
private static extern int WNetAddConnection2( NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags );

[DllImport( "Mpr.dll" )]
private static extern int WNetCancelConnection2( string lpName, int dwFlags, bool fForce );

[StructLayout( LayoutKind.Sequential )]
private class NETRESOURCE {
  public int dwScope          = 0;
  public int dwType           = 0;
  public int dwDisplayType    = 0;
  public int dwUsage          = 0;
  public string lpLocalName   = "";
  public string lpRemoteName  = "";
  public string lpComment     = "";
  public string lpProvider    = "";
}
const int RESOURCETYPE_DISK           = 0x00000001;
const int CONNECT_TEMPORARY           = 0x00000004;
使用示例

[DllImport( "Mpr.dll" )]
private static extern int WNetUseConnection( IntPtr hwndOwner, NETRESOURCE lpNetResource, string lpPassword, string lpUserID, int dwFlags, string lpAccessName, string lpBufferSize, string lpResult );

[DllImport( "Mpr.dll" )]
private static extern int WNetAddConnection2( NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags );

[DllImport( "Mpr.dll" )]
private static extern int WNetCancelConnection2( string lpName, int dwFlags, bool fForce );

[StructLayout( LayoutKind.Sequential )]
private class NETRESOURCE {
  public int dwScope          = 0;
  public int dwType           = 0;
  public int dwDisplayType    = 0;
  public int dwUsage          = 0;
  public string lpLocalName   = "";
  public string lpRemoteName  = "";
  public string lpComment     = "";
  public string lpProvider    = "";
}
const int RESOURCETYPE_DISK           = 0x00000001;
const int CONNECT_TEMPORARY           = 0x00000004;
OwneTuseConnection使用了很长时间,我今晚刚刚尝试了OwneTuseConnection 2

我用另一种方法把它关上

int iReturnValue = WNetCancelConnection2( @"\\192.168.5.254\packages", CONNECT_UPDATE_PROFILE, true );
注意:我对路径、用户名和密码使用变量,而不是字符串文字,仅在示例中更新

目标服务器是一个linux机器,在本例中,假设用户名和密码是字面上的“用户名”和“密码”,即它们的格式。我尝试将服务器名称添加到用户名中,例如“192.168.5.254\Username”,这会导致1219错误

如果我重新启动客户机系统,它在第一次尝试时不会出错,这使我相信这是在客户机端与服务器端缓存或未正确处理的东西,我还观察到两个不同linux服务器的相同行为,作为运行不同版本samba的远程位置


如果需要更多的信息,我可以提供,我在这里有点不知所措,所以非常感谢任何帮助。TIA

与我关于线程未被处理的理论相关,因为我刚才正在测试,我意识到情况可能并非如此。如果第二次更新在第一次更新完成后很快发生,则没有错误,只有在两次更新之间有短暂的暂停时才会发生。根据我的经验,通过指定远程共享名来断开与服务器的连接并不能按预期的方式工作。尽管这很烦人,但我建议您在建立连接时尝试映射驱动器号,以便可以使用驱动器号而不是共享名来断开连接。还可以使用LogonUser(使用
LOGON32\u LOGON\u NEW\u凭据)和模拟来为每个连接提供自己的MPR上下文。(我不确定。)MPR(多提供商路由器)是一个组件,用于确定需要调用哪个网络客户端才能处理给定的文件名。我只是对所有东西是如何结合在一起的有一个模糊的概念,这可能不是真正意义上的MPR。然而,我的想法是,拥有单独的登录会话可能会解决问题,因为据我所知,每个登录会话都有自己的一组网络连接。两个警告是:(a)我不确定
LOGON32\u logon\u NEW\u凭据
是否真的创建了一个新的登录会话,如果不是,它所做的任何改变是否会影响网络连接缓存;(b)我不确定模拟如何影响网络连接的使用,这意味着只有当您实际生成了单独的进程来代表您完成工作时,它才可能工作。