|
-
July 19th, 2011, 12:55 PM
#1
Mapped Drive to UNC
Using .NET 4
I'm trying to convert from Mapped Drive paths (e.g. "Z:\tmp\test.txt => \\server\tmp\test.txt") and I'm having mixed results.
I used a function from http://www.wiredprairie.us/blog/index.php/archives/22 that uses WNetGetConnection(http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx), which makes this arguably also a c++ question, and it worked the first time, but in subsequent uses it is returning error code 2250, which is ERROR_NO_NETWORK. I am very much still connected to the drive, and it worked minutes earlier, but no more.
Anyone have a better way or know what might be the issue?
Thanks!
Code for reference:
Code:
[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);
public static string DriveMapPathToUNC(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;
}
Last edited by Hoobs; July 19th, 2011 at 02:08 PM.
-
July 19th, 2011, 01:09 PM
#2
Re: Mapped Drive to UNC
NET USE /? will give you the parameters that you'd normally use.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\David>net use
New connections will be remembered.
There are no entries in the list.
C:\Users\David>
-
July 19th, 2011, 01:22 PM
#3
Re: Mapped Drive to UNC
Thanks for the reply, David.
NET USE tells me :
Status Local Remote Network
--------------------------------------------------------------------------
OK N: \\server1\ Microsoft Windows Network
Which tells me the connection should be okay.
As a little more information, this program is a service that will be open user-specified text files, and they might specify Mapped, UNC or local and I need to be able to handle all three. Since C# doesn't like Mapped paths, I'm resorting to this.
When I call WNetGetConnection on "N:" it returns 2250, even though net use still shows okay.
EDIT:
I tried making a basic C console program and it worked great, so I'm guessing it lies somewhere in the character encoding.
Last edited by Hoobs; July 19th, 2011 at 01:57 PM.
-
July 19th, 2011, 03:14 PM
#4
Re: Mapped Drive to UNC
New Resolution:
Since it was running in a service, the user running the program was Local System, not the logged in user, so the mapped drives were different. Running the service as myself made the C++ function below work 100% of the time. The C# version in OP was still hit-and-miss.
Old Resolution:
I resolved it, though not how I had hoped. Instead of trying to invoke through C Sharp, I just made a CLR DLL that had the C++ managed code, and imported that. For those who come after me, here's the C function that worked well:
Code:
static System::String^ MappedPathToUNC(System::String^ path)
{
DWORD MAX_DEVICE_LENGTH = 1000;
TCHAR* szDeviceName = new TCHAR[MAX_DEVICE_LENGTH];
memset(szDeviceName, '\0', MAX_DEVICE_LENGTH);
DWORD dwResult, cchBuff = sizeof(MAX_DEVICE_LENGTH);
char* charpath = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(path->Substring(0,2));
wchar_t* tpath = new wchar_t[MAX_DEVICE_LENGTH];
memset(tpath, '\0', MAX_DEVICE_LENGTH);
DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, charpath, -1, NULL, 0);
MultiByteToWideChar (CP_ACP, 0, charpath, -1, tpath, dwNum );
dwResult = WNetGetConnection(
tpath,
szDeviceName, &MAX_DEVICE_LENGTH);
System::String ^ str = gcnew System::String(szDeviceName);
str += path->Substring(2, path->Length-2);
return str;
}
Note: This function assumes the first two characters are a letter and a colon, like Z: or N:.
Last edited by Hoobs; July 19th, 2011 at 03:38 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|