Получить UNC-путь из локального или сопоставленного пути
в Delphi есть функция ExpandUNCFileName, которая принимает имя файла и преобразует его в эквивалент UNC. Он расширяет сопоставленные диски и пропускает локальные и уже расширенные местоположения.
образцы
C:FolderText.txt - > C:FolderText - ... txt
L:FolderSample.txt - > serverFolder1FolderSample.txt, где L: сопоставляется с serverFolder1
\серверпапкаобразец.odf - > serverFolderSample.ОДФ
есть ли простой способ сделать это в C# или мне придется использовать вызов Windows api WNetGetConnection, а затем вручную проверить те, которые не будут сопоставлены?
4 ответов
в BCL нет встроенной функции, которая будет делать эквивалент. Я думаю, что лучший вариант у вас есть pInvoking в WNetGetConnection, как вы предложили.
P / Invoke WNetGetUniversalName()
.
Я сделал это изменение код от www.pinvoke.net.
вот некоторый код C# с функцией-оболочкой LocalToUNC, который, кажется, работает нормально, хотя я не тестировал его широко.
[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);
}
}
попробуйте этот код, написанный в Delphi .Net
вы должны перевести его на 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;
тю.