Имеется программа обрабатывающая различные файловые пути (напр.: C:\Users\J.Doe
, \\Server\Share
, Z:\Mapped\Drive
). Для однозначной обработки файлов их пути приводятся к UNC-формату, если файл располагается не на локальном диске. Для избежания возникновения исключения PathTooLongException
можно к локальным путям добавлять префикс \\?\
, но в этом случае сам путь не обрабатывается, т.е. не раскрываются ссылки, относительные пути и т.д.. И насколько я понимаю, это не применимо к UNC-путям (поправьте, если не прав).
Нашел статью .NET 4.6.2 and long paths on Windows 10, но как понятно из названия, сие работает только с Windows 10 и не работает с UNC, а как быть со старыми версиями ОС и файлами в сети?
Как принято обходить эту ошибку? Можно ли получить доступ к файлу по UNC пути, если он длиннее MAX_PATH?
К сожалению, на старых версиях Windows придётся прибегать к прямому использованию WinAPI. Примеры кода есть в этой статье, придётся написать собственный вспомогательный класс вместо File
.
Я пользуюсь вот таким классом:
public static class LongPathFile
{
[Flags]
public enum EFileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000,
}
[Flags]
public enum EFileShare : uint
{
None = 0x00000000,
Read = 0x00000001,
Write = 0x00000002,
Delete = 0x00000004,
}
public enum ECreationDisposition : uint
{
New = 1,
CreateAlways = 2,
OpenExisting = 3,
OpenAlways = 4,
TruncateExisting = 5
}
[Flags]
public enum EFileAttributes : uint
{
Readonly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Directory = 0x00000010,
Archive = 0x00000020,
Device = 0x00000040,
Normal = 0x00000080,
Temporary = 0x00000100,
SparseFile = 0x00000200,
ReparsePoint = 0x00000400,
Compressed = 0x00000800,
Offline = 0x00001000,
NotContentIndexed = 0x00002000,
Encrypted = 0x00004000,
Write_Through = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern SafeFileHandle CreateFile(
string lpFileName,
EFileAccess dwDesiredAccess,
EFileShare dwShareMode,
IntPtr lpSecurityAttributes,
ECreationDisposition dwCreationDisposition,
EFileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
public static SafeFileHandle GetCreateHandle(string path)
{
var handle = CreateFile(
path,
EFileAccess.GenericWrite,
EFileShare.None,
IntPtr.Zero,
ECreationDisposition.CreateAlways,
0,
IntPtr.Zero);
var lastWin32Error = Marshal.GetLastWin32Error();
if (handle.IsInvalid)
throw new Win32Exception(lastWin32Error);
return handle;
}
public static FileStream Create(string path)
{
return new FileStream(GetCreateHandle(path), FileAccess.Write);
}
public static SafeFileHandle GetReadHandle(string path)
{
var handle = CreateFile(
path,
EFileAccess.GenericRead,
EFileShare.None,
IntPtr.Zero,
ECreationDisposition.OpenExisting,
0,
IntPtr.Zero);
var lastWin32Error = Marshal.GetLastWin32Error();
if (handle.IsInvalid)
throw new Win32Exception(lastWin32Error);
return handle;
}
public static FileStream OpenRead(string path)
{
return new FileStream(GetReadHandle(path), FileAccess.Read);
}
}
Использовать так же, как и File.Create
/File.OpenRead
:
using (var file = LongPathFile.Create(path))
stream.CopyTo(file);
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Из вне приходит произвольная строка и нужно определить ее язык
Суть проста В picturebox загружается картинка, потом по нажатию кнопки добавляется ватермарка НО! Сейчас добавляется только указанная в пути...
Имеется XML документ, из него идет парсинг значений полей и далее необходимо узнать тип значения записанный в строковой переменнойДля определения...