C# – Could not find a part of the path :While copying file on Mapped drive using Windows Service

cnet

I have a Windows Service which goes and update some files on the Network which is mapped as drive "Z:\". When i run the code from VS as administrator I am able to copy the file on the mapped drive but same thing fails when it is run from the Service which is running under administrator account.
The Mapped drive is created from same account under which service is running. Bit puzzling why its working when run from the VS but not from service.
Is it better to use UNC than network drive.
There is a workaround at below forum
http://support.microsoft.com/default.aspx?scid=kb;en-us;827421#appliesto
but it has used UNC not mapped drive.

Best Answer

We experienced this as well, and while I can't tell you WHY our resolution worked, i can tell you WHAT worked.

Map the drive in the code. Don't rely on the drive being mapped just because you're using the same account.

Based on the behavior we saw, this is what i would GUESS was happening in our situation and what's happening in yours.

The service we had issues with used a drive that was mapped in a login script. If we had the machine logged in as the same user the service was using, it worked, but if not it wouldn't work. Based on that, I surmised that the drive simply isn't mapped because the service doesn't really "log on".

Mapping the drive in code fixed it.

As a side note, you can also reference the UNC path directly, but we had permissions issues with that as well. Mapping the drive, passing in a username and password worked much better for us.

Our code for doing this:

public static class NetworkDrives
    {
        public static bool  MapDrive(string DriveLetter, string Path, string Username, string Password)
        {

            bool ReturnValue = false;

            if(System.IO.Directory.Exists(DriveLetter + ":\\"))
            {
                DisconnectDrive(DriveLetter);
            }
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.FileName = "net.exe";
            p.StartInfo.Arguments = " use " + DriveLetter + ": " + '"' + Path + '"' + " " + Password + " /user:" + Username;
            p.Start();
            p.WaitForExit();

            string ErrorMessage = p.StandardError.ReadToEnd();
            string OuputMessage = p.StandardOutput.ReadToEnd();
            if (ErrorMessage.Length > 0)
            {
                throw new Exception("Error:" + ErrorMessage);
            }
            else
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public static bool DisconnectDrive(string DriveLetter)
        {
            bool ReturnValue = false;
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.FileName = "net.exe";
            p.StartInfo.Arguments = " use " + DriveLetter + ": /DELETE";
            p.Start();
            p.WaitForExit();

            string ErrorMessage = p.StandardError.ReadToEnd();
            string OuputMessage = p.StandardOutput.ReadToEnd();
            if (ErrorMessage.Length > 0)
            {
                throw new Exception("Error:" + ErrorMessage);
            }
            else
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }

    }

Using the above class, you can map and disconnect the drive at will. If this is a service, I would recommend mapping the drive just before you need it and disconnecting the drive immediately after you need it.