Search code examples
c#windowsuncmounted-volumes

How to return the UNC path of a remote folder and the local path of a local folder


I have a shell extension which allows users to right-click a folder and then passes the path as an argument to a utility.

To work in a network environment, it has to resolve any mounted drives. For example if the path were P:\projects\P123 it might resolve to \\server3\business\projects\P123

The following code from Stackoverflow has worked fine, but I now need to handle situations where the user right-clicks on the folder of a local drive. For example if the folder is c:\users\JohnDoe\documents I need it to return this very same path. Unfortunately for a path like this it returns \users\JohnDoe\documents which obviously won't work.

I'm a novice so if you can help, please could you spell out the advice so that someone with limited experience can understand it - thanks.

  public string GetUNCPath(string path)
        {
            string rval = path;
            string driveprefix = path.Substring(0, 2);
            string unc;

            if (driveprefix != "\\")
            {
                ManagementObject mo = new ManagementObject();
                try
                {
                    mo.Path = new ManagementPath(String.Format("Win32_LogicalDisk='{0}'", driveprefix));
                    unc = (string)mo["ProviderName"];
                    rval = path.Replace(driveprefix, unc);
                }
                catch
                {
                    throw;
                }
            }

            if (rval == null)
            { rval = path; }

            return rval;
        }

Solution

  • In the end I worked it out myself. All I needed was to test whether the drive was local. Here's the working code:

     public string GetUNCPath(string path)
            {
                if (!IsNetworkDrive(path)) return path;   // If it's not a network path, just return the path unchanged
    
                string rval = path;
                string driveprefix = path.Substring(0, 2);
                string unc;
    
                if (driveprefix != "\\")
                {
                    ManagementObject mo = new ManagementObject();
                    try
                    {
                        mo.Path = new ManagementPath(String.Format("Win32_LogicalDisk='{0}'", driveprefix));
                        unc = (string)mo["ProviderName"];
                        rval = path.Replace(driveprefix, unc);
                    }
                    catch
                    {
                        throw;
                    }
                }
    
                if (rval == null)
                { rval = path; }
    
                return rval;
            }
            public bool IsNetworkDrive(string path)
            {
                FileInfo f = new FileInfo(path);
                string driveRoot = Path.GetPathRoot(f.FullName); // Example return "C:\"
                // find the drive 
                System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();
                foreach (var drive in drives)
                {
                    string driveName = drive.Name; // C:\, E:\, etc:\
                    if (driveName == driveRoot) // if this is the drive 
                    {
                        System.IO.DriveType driveType = drive.DriveType;
                        if (driveType == System.IO.DriveType.Network) return true;
                    }
                }
                return false; 
            }