如何强制Windows重新连接到网络驱动器

问题描述:

我们尝试访问的目录是网络目录内,但得到错误的结果(C#/ Windows)中:如何强制Windows重新连接到网络驱动器

var exists = Directory.Exists("Z:\\Sessions\\Data1"); 

“Z”是网络目录,“会话“是一个录制软件不断创建目录(例如”Data1“)并将一些数据放入其中的目录。 看来,Windows缓存关于Data1的错误状态:该方法返回false。但是当我通过资源管理器访问目录时,它就在这里。当我用Explorer访问目录后运行方法(Directory.Exists)时,它返回true。当然,我可以保证该目录在第一次尝试时实际存在。

这种行为的原因是什么?我能做些什么呢?

编辑: 看来,Windows无法将网络驱动器连接到远程计算机。当我尝试使用Explorer浏览到目录时,它会自动尝试连接驱动器。

因此,问题变化: 有没有办法强制窗户尝试通过.NET重新连接?

解决方案: Reconnecting a disconnected network drive

+0

如果您使用命令提示符下的“DIR”命令访问目录,您是否收到正确的信息?那就是:'dir Z:\ Sessions \ Data1'。 – 2011-12-25 14:24:14

+0

不,通过命令提示符访问目录不会刷新网络驱动器连接。请参阅我的编辑... – nepa 2011-12-26 10:20:54

什么是这种现象的原因?从documentation

报价:

如果没有至少只读权限的目录, 有不存在的方法将返回false。


我能做些什么呢?

确保您在一个至少具有只读权限的帐户下运行.NET应用程序以访问此文件夹。请注意,如果您正在ASP.NET应用程序中编写此应用程序,则可能不会如此,具体取决于您将Web服务器配置为在哪个帐户下执行您的应用程序,请采取必要步骤为该帐户授予权限。

+0

作为OP提到,“当我用Explorer访问目录后运行该方法(Directory.Exists)时,它返回true。” - 这意味着最有可能是缓存问题,而不是权限 – 2011-12-25 13:28:03

+1

@ EugeneMayevski'EldoSCorp,当您使用资源管理器时,您正在您的帐户下运行它。当您运行ASP.NET应用程序时,它可以在完全不同的帐户下运行。所以我猜测OP为验证目录存在而进行的测试并未在相同的条件下执行:在第一种情况下,他使用自己的帐户,而在第二种情况下使用其他帐户(我们只能猜测哪一个在这个阶段,由于OP提供了关于他的申请的正确背景)。 – 2011-12-25 13:29:14

+0

由于我所做的一些发现,问题发生了变化,请参阅我的编辑。 – nepa 2011-12-26 10:22:07

我也使用远程驱动器,它需要几秒钟的时间才能连接,所以我只是等待并且每次都工作。如果它没有连接,它会发送一封电子邮件,我会检查它。

 logger.Info("Create Z: drive "); 
     System.Diagnostics.Process process = new System.Diagnostics.Process(); 
     System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); 
     startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 
     startInfo.FileName = "cmd.exe"; 
     startInfo.Arguments = @"/C net use z: \\" + Tools.servername + @"\SHARE_NAME_HERE /user:USER_NAME_HERE PASSWORD_HERE"; 
     process.StartInfo = startInfo; 
     process.Start(); 
     logger.Info("Z: drive created "); 

     // wait get Z: 
     int xtimestimeout = 5; 
     while (!Directory.Exists(@"Z:\") & (xtimestimeout > 0)) 
     { 
      Application.DoEvents(); 
      SetBalloonTip(@"Program", @"connecting... please wait"); 
      ShowBalloon(); 
      logger.Info("Creating Z:... waiting..."); 
      Application.DoEvents(); 
      System.Threading.Thread.Sleep(3000); 
      xtimestimeout -= 1; 
     } 

     // check for sucessfull creation of Z: in server Z:\somedirectory 
     if (!Directory.Exists(@"Z:\")) 
     { 
      SendEmail2("Oh my... help!", "drive Z: not created <<< CHECK!"); 
      logger.Info("Z: email sent because of not created"); 
     } 
     logger.Info("Z: drive created successfully."); 
+0

好吧,有人用-1标记我的答案。我不明白为什么,因为我也和问题一样,并且这个代码解决了这个问题。此代码的工作原理,只使用.net代码,而不是外部库作为标记为解决方案的答案。 – 2014-09-08 10:06:33

+0

别担心,我反对票。它实际上是一个很好的解决方案,正是我想要做的。但我也不希望cmd窗口出现。但是,我没有测试过你的代码,但它看起来很有前途。谢谢。 – xmen 2015-06-08 06:01:06

我不知道这MPR.DLL的解决方案链接的版本上面的工作,但我使用Win7和有一个稍微不同的版本(虽然相似)。此入口点是:

[DllImport("mpr.dll", SetLastError = true, EntryPoint = "WNetRestoreSingleConnectionW", CharSet = CharSet.Unicode)] 
    internal static extern int WNetRestoreSingleConnection(IntPtr windowHandle, 
                  [MarshalAs(UnmanagedType.LPWStr)] string localDrive, 
                  [MarshalAs(UnmanagedType.Bool)] bool useUI); 

则:

IntPtr hWnd = new IntPtr(0); 
int res = WNetRestoreSingleConnection(hWnd, <your drive path>, false); 

你必须添加自己的错误检查/处理。