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

Posted

技术标签:

【中文标题】如何强制 Windows 重新连接到网络驱动器【英文标题】:How to force Windows to reconnect to network drive 【发布时间】:2012-01-27 14:56:24 【问题描述】:

我们尝试访问网络目录中的目录但得到错误结果(C#/Windows):

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

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

这种行为的原因是什么?我该怎么办?

编辑: windows似乎无法将网络驱动器连接到远程计算机。当我尝试使用资源管理器导航到目录时,它会自动尝试连接驱动器。

所以问题发生了变化: 有没有办法强制 Windows 尝试通过 .NET 重新连接?

解决方案: Reconnecting a disconnected network drive

【问题讨论】:

如果您在命令提示符下使用DIR 命令访问该目录,您得到的信息是否正确?即:dir Z:\Sessions\Data1. 否,通过命令提示符访问目录不会刷新网络驱动器连接。请查看我的编辑... 【参考方案1】:

我不确定上面的解决方案链接适用于哪个版本的 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);

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

【讨论】:

即使 API 没有记录(仍然?!?)这似乎在 Windows 10 上工作【参考方案2】:

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

        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.");

【讨论】:

好吧,有人用 -1 标记我的答案。我不明白为什么,因为我也有与问题相同的情况,这段代码解决了它。此代码有效且仅使用 .net 代码,而不是外部库作为标记为解决方案的答案。 别担心,我反投了。它实际上是一个很好的解决方案,正是我想要做的。但我也不希望出现 cmd 窗口。但是,我尚未测试您的代码,但它看起来很有希望。谢谢。【参考方案3】:

这种行为的原因是什么?

引用自documentation:

如果您没有对该目录的最低只读权限, Exists 方法将返回 false。


我该怎么办?

确保您在至少具有访问此文件夹的只读权限的帐户下运行 .NET 应用程序。请注意,如果您是在 ASP.NET 应用程序中编写此代码,则可能不会出现这种情况,因此根据您将 Web 服务器配置为在哪个帐户下执行应用程序,采取必要的步骤来授予此帐户的权限。

【讨论】:

正如 OP 所提到的,“当我在使用 Explorer 访问目录后运行方法 (Directory.Exists) 时,它返回 true。” - 这很可能是缓存问题而不是缓存问题权限 @EugeneMayevski'EldoSCorp,当您使用资源管理器时,您是在您的帐户下运行它。当您运行 ASP.NET 应用程序时,它可以在完全不同的帐户下运行。所以我猜 OP 为验证目录是否存在而执行的测试不是在相同的条件下执行的:在第一种情况下,他使用了自己的帐户,而在第二种情况下,使用了其他一些帐户(我们只能猜测哪个在这个阶段,因为 OP 提供了关于他的应用程序的完全 0 上下文)。 由于我的一些发现,问题发生了变化,请查看我的修改。

以上是关于如何强制 Windows 重新连接到网络驱动器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 中强制“无法访问目标网络”ping 结果

如何使用映射的网络驱动器通过数据源 (ODBC) 连接到 Access 数据库?

电脑提示windows无法连接到网络怎么办?

使用用户名和密码连接到网络驱动器

映射网络磁盘变成本地磁盘

如何强制 iPad 启动 wifi 连接?