Converting a local path to an UNC path with WNetGetUniversalName from C#
Posted: (EET/GMT+2)
Using shared (mapped) network drives is common in many organizations, but sometimes you want to convert the local path (say, U:\) to the UNC path and share name to become computer-independent. The Windows Win32 API has the function named WNetGetUniversalName that is able to do such a conversion, but how would you call this method from managed code? Here's the solution.
Firstly, you need to define the function WNetGetUniversalName as an external function so that you can use using .NET P/Invoke. The function declaration is:
[DllImport("mpr.dll")]
public static extern int WNetGetUniversalName(
string lpLocalPath,
int dwInfoLevel,
ref StringBuilder lpBuffer,
ref int lpBufferSize);
Next, you will need several constants to help you with this function:
const int UNIVERSAL_NAME_INFO_LEVEL = 1; const int ERROR_MORE_DATA = 234; // optional: const int ERROR_NOT_CONNECTED = 2250; const int MAX_PATH = 260;
Here, only the first two constants are needed, but the two latter can be useful as well. For example, if you pass in an invalid network share name, such as one that doesn't exist, WNetGetUniversalName will return ERROR_NOT_CONNECTED (2250).
Now then, here's a wrapper around the said API function:
public string ConvertLocalPathToUnc(
string localPath)
{
StringBuilder buffer = new StringBuilder();
int size = 0;
// First call WNetGetUniversalName with an
// empty buffer to get size of buffer needed.
int retVal = WNetGetUniversalName(
localPath, UNIVERSAL_NAME_INFO_LEVEL,
ref buffer, ref size);
if (retVal == ERROR_MORE_DATA)
{
// WNetGetUniversalName returns the space
// needed in size, now allocate space for a
// buffer of this size.
buffer = new StringBuilder(size);
retVal = WNetGetUniversalName(
localPath, UNIVERSAL_NAME_INFO_LEVEL,
ref buffer, ref size);
if (retVal != 0)
{
throw new Win32Exception(retVal);
}
}
else
{
throw new Win32Exception(retVal);
}
return buffer.ToString();
}
Here, I'm first calling WNetGetUniversalName with a buffer of zero size, in which case WNetGetUniversalName returns the proper size of the buffer needed. Then I re-allocate a StringBuilder object with the given size, and call WNetGetUniversalName again. If errors occur, the code raises a Win32Exception. For example, in the case of the ERROR_NOT_CONNECTED error, the exception message is "This network connection does not exist."
Finally, here's an example how to call the ConvertLocalPathToUnc method:
string localPath = "U:\\"; string unc = ConvertLocalPathToUnc(localPath); MessageBox.Show(localPath + " = " + unc);
This would simply display on the screen a message box with text similar to the following:
U:\ = \\myserver\myshare\
Keywords: howto, c#, .net, how to convert path to unc, get unc path from local path, network path, network share