从本地路径或映射路径获取UNC路径
在Delphi中有一个函数ExpandUNCFileName,它接受一个文件名并将其转换为UNC等效项。它扩展映射的驱动器并跳过本地和已扩展的位置。从本地路径或映射路径获取UNC路径
样品
C:\文件夹\ TEXT.TXT - > C:\文件夹\ TEXT.TXT
L:\文件夹\ Sample.txt的 - > \\服务器\ Folder1中\文件夹\ Sample.txt的L:映射到\\ server \ Folder1 \
\\ server \ Folder \ Sample.odf - > \ server \ Folder \ Sample.odf
是否有一种简单的方法可以在C#中执行此操作,必须使用Windows API调用WNetGetConnection然后手动检查那些不会被映射的那些?
BCL中没有内置功能,它可以完成同等功能。我认为你拥有的最好的选择是按照你的建议进入WNetGetConnection。
试试这个代码,写在德尔福净
你必须把它翻译成C#
function WNetGetUniversalName; external;
[SuppressUnmanagedCodeSecurity, DllImport(mpr, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'WNetGetUniversalNameA')]
function ExpandUNCFileName(const FileName: string): string;
function GetUniversalName(const FileName: string): string;
const
UNIVERSAL_NAME_INFO_LEVEL = 1;
var
Buffer: IntPtr;
BufSize: DWORD;
begin
Result := FileName;
BufSize := 1024;
Buffer := Marshal.AllocHGlobal(BufSize);
try
if WNetGetUniversalName(FileName, UNIVERSAL_NAME_INFO_LEVEL,
Buffer, BufSize) <> NO_ERROR then Exit;
Result := TUniversalNameInfo(Marshal.PtrToStructure(Buffer,
TypeOf(TUniversalNameInfo))).lpUniversalName;
finally
Marshal.FreeHGlobal(Buffer);
end;
end;
begin
Result :=System.IO.Path.GetFullPath(FileName);
if (Length(Result) >= 3) and (Result[2] = ':') and (Upcase(Result[1]) >= 'A')
and (Upcase(Result[1]) <= 'Z') then
Result := GetUniversalName(Result);
end;
再见。
下面是一些包装函数LocalToUNC的C#代码,它似乎工作正常,但我没有广泛地测试它。
[DllImport("mpr.dll")]
static extern int WNetGetUniversalNameA(
string lpLocalPath, int dwInfoLevel, IntPtr lpBuffer, ref int lpBufferSize
);
// I think max length for UNC is actually 32,767
static string LocalToUNC(string localPath, int maxLen = 2000)
{
IntPtr lpBuff;
// Allocate the memory
try
{
lpBuff = Marshal.AllocHGlobal(maxLen);
}
catch (OutOfMemoryException)
{
return null;
}
try
{
int res = WNetGetUniversalNameA(localPath, 1, lpBuff, ref maxLen);
if (res != 0)
return null;
// lpbuff is a structure, whose first element is a pointer to the UNC name (just going to be lpBuff + sizeof(int))
return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(lpBuff));
}
catch (Exception)
{
return null;
}
finally
{
Marshal.FreeHGlobal(lpBuff);
}
}
+1因为'Marshal.ReadIntPtr(lpBuff)'得到字符串缓冲区。这比pinvoke.net上的顶部例子更清晰,他们在这里做了一些很灵活的指针算术,因为他们做了一个无法证明的假设,即字符串缓冲区直接位于'UNIVERSAL_NAME_INFO'结构之后。 – herzbube 2014-04-14 16:32:58
非常感谢这么多 – 2010-08-30 05:47:31