Что не так с моим вызовом WINAPI для обработки длинных путей к файлам?
-
23-08-2019 - |
Вопрос
Я пытался найти лучший способ копирования файлов в Windows с глубокими путями (файлы, а не папки, поэтому о робокопировании не может быть и речи).Лучшее решение, которое я смог придумать, — это написать собственное решение.Мне удалось написать код для обработки каталогов с путями длиной 10 000 символов, но использование того же подхода, похоже, не работает для фактического копирования файлов.Я устал использовать библиотеки System.IO с префиксом \?\ перед путями, и это, похоже, не сработало.
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFile(string lpExistingFileName, string lpNewFileName,
bool bFailIfExists);
public static bool CopyFile(string source, string dest)
{
source = fixPathForLong(source);
dest = fixPathForLong(dest);
return CopyFile(source, dest, false);
}
private static string fixPathForLong(String path)
{
if (!path.StartsWith(@"\\?\"))
path = @"\\?\" + path;
return path;
}
Решение
Если вызов CopyFile (а не ваша перегрузка, объявление P/Invoke) возвращает false, я бы выдал исключение Win32Exception:
public static void CopyFile(string source, string dest)
{
source = fixPathForLong(source);
dest = fixPathForLong(dest);
if (!CopyFile(source, dest, false))
{
throw new Win32Exception();
}
}
Конструктор по умолчанию для класса Win32Exception выполнит вызов GetLastError и предоставит вам более подробную информацию об ошибке и причину сбоя операции.
Другие советы
Стоит ли вместо этого вызывать функцию CopyFileW?Обратите внимание на букву W в конце.Кроме того, я не знаю, используете ли вы пути UNC.В этом случае вам нужно вместо этого поставить префикс «\\?\UNC».
Это хорошая статья для обработки длинных путей.
http://blogs.msdn.com/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx