Подтвердить что ты не робот

С# удаление папки с длинными путями

Я пытаюсь удалить папку, и удаление не выполняется из-за папки, содержащей длинные пути. Я предполагаю, что мне нужно использовать что-то другое вместо dir.Delete(true), кто-то пересек этот мост раньше?

Большое спасибо

 try
{
 var dir = new DirectoryInfo(@FolderPath);
 dir.Attributes = dir.Attributes & ~FileAttributes.ReadOnly;
 dir.Delete(true);
}
catch (IOException ex)
{
 MessageBox.Show(ex.Message);
}

Это путь, о котором идет речь: \ server\share\dave\Private\Careers\Карьера Ed\Fun Карьера Образование \Chris не используется 2006 to07\old 4.Careers Area Activity Неделя 1 30.10.06 или 6.11.06 или 13.11.06 Знакомство с уровнями работы и ресурсами карьеры\Профессиональные области и уровни работы Справочная информация для преподавателя [1].doc

4b9b3361

Ответ 1

В API Windows максимальная длина для пути - MAX_PATH, которая определена как 260 символов. Локальный путь структурирован в следующем порядке: буква диска, двоеточие, обратная косая черта, компоненты имени, разделенные обратными косыми чертами, и завершающий нулевой символ. Например, максимальный путь на диске D - "D:\некоторая строка с символом 256 символов" <NUL> ", где" <NUL> "представляет невидимый завершающий нулевой символ для текущей кодовой страницы системы. (Символы <> используются здесь для визуальной ясности и не могут быть частью допустимой строки пути.) [MSDN]

Unicode-версии нескольких функций допускают максимальную длину пути, равную примерно 32 000 символов, состоящую из компонентов длиной до 255 символов. Чтобы указать этот путь, используйте префикс "\\?\". Максимальный путь 32 000 символов является приблизительным, поскольку префикс "\\?\" Может быть расширен до более длинной строки, и расширение распространяется на общую длину.

Например, "\\?\D:\<path>". Чтобы указать такой путь UNC, используйте префикс "\\?\UNC\". Например, "\\?\UNC\<server>\<share>". Эти префиксы не используются как часть самого пути. Они указывают, что путь должен быть передан системе с минимальной модификацией, а это означает, что вы не можете использовать косые черты для представления разделителей путей или период для представления текущего каталога. Кроме того, вы не можете использовать префикс "\\?\" С относительным путем. Относительные пути ограничены символами MAX_PATH.

У оболочки и файловой системы могут быть разные требования. Можно создать путь с API, который интерфейс UI оболочки не может обрабатывать.

Синтаксис С#:

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool DeleteFile(string path);

Дополнительные сведения о классе см. В разделе " Системное пространство имен" - MSDN

Выдержки из:

Пути файловой системы: как долго слишком долго? - Ужас кодирования

Функция DeleteFile (Windows) - MSDN

Ответ 2

Лучше я до сих пор это

public static class IOHelper
{
    public static void DeleteDirectory(DirectoryInfo directoryInfo)
    {
        var emptyTempDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), "IOHelperEmptyDirectory"));
        emptyTempDirectory.Create();
        var arguments = string.Format("\"{0}\" \"{1}\" /MIR", emptyTempDirectory.FullName, directoryInfo.FullName);
        using (var process = Process.Start(new ProcessStartInfo("robocopy")
                                            {
                                                Arguments = arguments,
                                                CreateNoWindow = true,
                                                UseShellExecute = false,
                                            }))
        {
            process.WaitForExit();
        }
        directoryInfo.Delete();
    }
}

Ответ 3

Ограничение в 260 символов (я предполагаю, что тот, с которым вы работаете) является проблемой в Windows, а не в .NET, к сожалению, поэтому работать с ней может быть сложно.

может работать с ним, изменяя рабочий каталог таким образом, чтобы относительный путь для удаления был менее 260 символов; Я не знаю, будет ли это работать или нет.

то есть:.

var curDir = Directory.GetCurrentDirectory();
Environment.CurrentDirectory = @"C:\Part\Of\The\Really\Long\Path";
Directory.Delete("Relative\Path\To\Directory");
Environment.CurrentDirectory = curDir;

Ответ 4

Я не знаю, открыт ли этот вопрос, но я решил проблему. Код был разработан на машине win7 с VS2008. Это шаги, которые я предпринял для решения проблемы.

  • Создать пустой проект VS С#
  • Добавьте ссылку на этот COM-объект: время выполнения сценариев microsoft
  • Добавить скрипт использования; в ваш список использования
  • Где-то в вашем коде создайте функцию, похожую на это:

    private static void DeletePathWithLongFileNames(string path)
    {
        var tmpPath = @"\\?\"+ path
        FileSystemObject fso = new FileSystemObjectClass() as FileSystemObject;
        fso.DeleteFolder(tmpPath, true); 
    }
    

Параметр Path - это каталог, который вы хотите удалить. Функция добавляет сигнатуру пути Unicode, создает экземпляры FileSystemObject и удаляет путь unicode и все его содержимое.

  • Скомпилируйте программу, запустите полученные .exe файлы с правами администратора (запустите как Administrator на win7), найдите каталог, который вы хотите удалить, и примените к нему эту функцию. Затем просмотрите длинные имена файлов.

Излишне говорить, что это мощно... и опасно. С большой силой приходит большая ответственность:-)

Ответ 5

Это то, что я использую для удаления домашних каталогов, где часто встречаются длинные пути:

public static void DirectoryDeleteLong(string directoryPath)
{
    var emptyDirectory = new DirectoryInfo(Path.GetTempPath() + "\\TempEmptyDirectory-" + Guid.NewGuid());
    try
    {
        emptyDirectory.Create();
        using (var process = new Process())
        {
            process.StartInfo.FileName = "robocopy.exe";
            process.StartInfo.Arguments = "\"" + emptyDirectory.FullName + "\" \"" + directoryPath + "\" /mir /r:1 /w:1 /np /xj /sl";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.Start();
            process.WaitForExit();
        }
        emptyDirectory.Delete();
        new DirectoryInfo(directoryPath).Attributes = FileAttributes.Normal;
        Directory.Delete(directoryPath);
    }
    catch(IOException) { }
}

Это похоже на решение, опубликованное Саймоном, но также:

  • Снижает максимальный допустимый лимит robocopy по умолчанию.
  • Сбрасывает атрибуты, поскольку файл directory.delete завершится с ошибкой на все, что помечено как только для чтения.
  • Создает уникальное имя пустого каталога, поэтому оно работает с несколькими потоками.

Ответ 6

Проверьте API Win32: http://msdn.microsoft.com/en-us/library/aa363915%28VS.85%29.aspx

Там говорится: "В версии ANSI этой функции имя ограничено символами MAX_PATH. Чтобы расширить этот предел до 32 767 символов, вызовите версию функции Unicode и добавьте" \?\ "к пути".

Добавьте pinvoke:

using System;  
using System.Runtime.InteropServices;  
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]  
[return: MarshalAs(UnmanagedType.Bool)]  
internal static extern bool DeleteFile(string lpFileName);

Используйте его:

public static void DeleteLong(string fileName) {

    string LongName = @"\\?\" + fileName;
    DeleteFile(formattedName);
}

Ответ 8

В следующей ссылке показана внутренняя реализация .NET для поддержки длинного пути в System.IO, она не самая легкая для чтения, созданная с помощью Reflector, но содержит множество примеров работы с API-интерфейсами Win32, упомянутых ранее.

http://reflector.webtropy.com/default.aspx/[email protected]/[email protected]/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/IO/[email protected]/1305376/[email protected]

Было бы неплохо, если бы эта функция была доступна через System.IO, так как поддержка там явно!

Ответ 9

Я создал управляемую библиотеку .Net для работы с файлами и папками.

https://github.com/DotNetIO

var fs = LocalFileSystem.Instance : FileSystem

^^^^ место в IoC

fs.GetDirectory(@"C:\\a very very long path ...\with\subdirs\and files.txt").Delete();

Приветствия