12

We try to access a directory which is within a network directory but get wrong results (C#/Windows):

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

"Z" is the network directory, "Sessions" is a directory where a recording software constantly creates directories (e.g. "Data1") and puts some data in it. It seems that Windows caches the wrong state about Data1: The method returns false. But when I access the directory via Explorer it's here. When I run the method (Directory.Exists) after accessing the directory with Explorer, it returns true. Of course I can guarantee that the directory actually exists at the first attempt.

What is the reason for this behaviour? What can I do about it?

Edit: It seems that windows could not connect the network drive to the remote computer. When I try to navigate into the directory with Explorer it automatically tries to connect the drive.

So the question changes: Is there a way to force windows to try a reconnect via .NET?

Solution: Reconnecting a disconnected network drive

Community
  • 1
  • 1
nepa
  • 1,421
  • 2
  • 18
  • 28
  • If you access the directory with the `DIR` command from the command prompt, do you get the correct information? That is: `dir Z:\Sessions\Data1`. – Jim Mischel Dec 25 '11 at 14:24
  • No, accessing the directory via command prompt doesn't refresh the network drive connection. Please see my edit... – nepa Dec 26 '11 at 10:20

3 Answers3

7

I'm not sure which version of mpr.dll the solution link above works with, but I am using Win7 and have a slightly different version (although similar). This entry point is:

    [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);

then:

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

You'll have to add your own error checking / handling.

Jess
  • 2,991
  • 3
  • 27
  • 40
2

I too use a remote drive and it takes a few seconds to connect, so I just wait and works every time. If it does not connect, it will send an email and I will check it.

        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.");
Roger Deep
  • 162
  • 1
  • 6
  • Well, someone flag my answer with -1. I don't understand WHY because I too have the same situation as the question and this code solves it. This code works and only uses .net code, not external library's as the answer that was marked as solution. – Roger Deep Sep 08 '14 at 10:06
  • Dont worry, I counter voted it. Its actually a good solution, exactly what I'm trying to do. But I also do not want cmd window to appear. However, I haven't tested your code, but it looks promising. Thank you. – xmen Jun 08 '15 at 06:01
0

What is the reason for this behaviour?

Quote from the documentation:

If you do not have at a minimum read-only permission to the directory, the Exists method will return false.


What can I do about it?

Ensure that you are running your .NET application under an account that has at least read-only permission to access this folder. Notice that if you are writing this in an ASP.NET application this probably won't be the case so depending on which account you configured your web server to execute your application under, take the necessary steps to grant permissions to this account.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • as the OP mentioned, "When I run the method (Directory.Exists) after accessing the directory with Explorer, it returns true. " - which means that most likely it's a problem of caching rather than of permissions – Eugene Mayevski 'Callback Dec 25 '11 at 13:28
  • 1
    @EugeneMayevski'EldoSCorp, when you use the Explorer you are running it under your account. When you are running an ASP.NET application it could run under an entirely different account. So I guess that the test that the OP performed to verify that the directory exists wasn't performed at equal conditions: at the first case he used his own account whereas in the second some other account is used (we could only be guessing which one at this stage as the OP provided exactly 0 context about his application). – Darin Dimitrov Dec 25 '11 at 13:29
  • The question changed due to some discoveries I made, please see my edits. – nepa Dec 26 '11 at 10:22