Wednesday, May 12, 2010

Accessing Network Drive in C#

Problem:

One of the requirements of the product that I was doing is like this: There will be a screen in a windows based application and it consists of a combo box.  

The combo box should display the network drives of the computer. For those who are less literate about network drives; Network Drives are those locations that are mapped to a drive or folder in another system which can be accessed over network. Usually it is often painful to manually navigate to the network location and access the files there. So windows allow us to create network drives on our machines such that we can access the desired network location with just one single click.

How to create a Network Drive?

The creation of network drives is a very simple process.

Open My Computer --> Select tools from the menu bar--> Select the Map Network Drive option.

This opens a window which has a combo box with the existing network drives and non networking drives. Upon selecting a drive the text box below the drop down list will display the path that the network is mapped to. Once you select the drive letter from the combo box , Enter the Network path in the text box and click Finish. Now you should be able to view the network drives in the my computer screen.

Solution to the Problem:

If you have ever worked on .NET you would certainly know how vast the base class library of .NET is. We can do many things with it. Yet, we cannot do everything using just the .NET framework and the BCL. Windows OS( XP,VISTA,WINDOWS 7) uses a special assembly called 'mrp.dll". mpr.dll is a module containing functions that are used to handle communication between the Windows operating system and the installed network providers. This assembly basically takes care of the relation between Drive Name Versus the Network Path. So we use the same .dll to fetch us the information that we need. The assembly should be referred as an external assembly and values should be passed to it.  In order to do this we use the DllImport attribute method to point to the mpr.dll. We must point the Drive letters to the external Dll this should be done with the help of MarshallAs  attribute.

Have a look at the folowing code.

public static class Pathing
{
   [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
   public static extern int WNetGetConnection(
       [MarshalAs(UnmanagedType.LPTStr)] string localName,
       [MarshalAs(UnmanagedType.LPTStr)] StringBuilder remoteName,
       ref int length);
   /// <summary>
   /// Given a path, returns the UNC path or the original. (No exceptions
   /// are raised by this function directly). For example, "P:\2008-02-29"
   /// might return: "\\networkserver\Shares\Photos\2008-02-09"
   /// </summary>
   /// <param name="originalPath">The path to convert to a UNC Path</param>
   /// <returns>A UNC path. If a network drive letter is specified, the
   /// drive letter is converted to a UNC or network path. If the
   /// originalPath cannot be converted, it is returned unchanged.</returns>
   public static string GetUNCPath(string originalPath)
   {
       StringBuilder sb = new StringBuilder(512);
       int size = sb.Capacity;
       // look for the {LETTER}: combination ...
       if (originalPath.Length > 2 && originalPath[1] == ':')
       {
           // don't use char.IsLetter here - as that can be misleading
           // the only valid drive letters are a-z && A-Z.
           char c = originalPath[0];
           if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
           {
               int error = WNetGetConnection(originalPath.Substring(0, 2),
                   sb, ref size);
               if (error == 0)
               {
                   DirectoryInfo dir = new DirectoryInfo(originalPath);
                   string path = Path.GetFullPath(originalPath)
                       .Substring(Path.GetPathRoot(originalPath).Length);
                   return Path.Combine(sb.ToString().TrimEnd(), path);
               }
           }
       }
       return originalPath;
   }
}


Read more: C# Corner

Posted via email from jasper22's posterous