Почему .NET не может определять каталоги с длинными путями к файлам? - PullRequest
4 голосов
/ 11 июня 2019

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

void TestLongPath(DirectoryInfo testDirectory)
{
    if (testDirectory.Exists)
    {
        try
        {
            testDirectory.GetFiles("SomeFileNamePattern*");
        }
        catch (System.IO.DirectoryNotFoundException)
        {
            Console.WriteLine("Long path test failed for " + testDirectory.FullName);
        }
    }
}

Мой файл app.manifest содержит:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
        <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
    </windowsSettings>
</application>

Но все, что было сделано, это изменило ошибку с PathTooLongException на DirectoryNotFoundException.

Вот мой App.config:

<?xml version="1.0" encoding="utf-8"?><configuration>
<startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
<runtime>
    <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" />
</runtime></configuration>

Я в Windows 10 Pro, использую Visual Studio 2019 16.1.1. Я нацеливаюсь на .NET 4.7.2.

Как мне перечислить файлы в этих слишком длинных каталогах? Они находятся на общем сетевом диске, которым я не могу управлять, поэтому переименование каталогов мне не подходит.

1 Ответ

1 голос
/ 11 июня 2019

Я решил, используя информацию отсюда: Каково максимальное количество символов или длины для Каталога?

Для .NET 4.6.2 или новее: «Switch.System.IO.UseLegacyPathHandling = false; Switch.System.IO.BlockLongPaths = false» в App.Config не имеет никакого эффекта.

Вам не нужно добавлять префиксы к путям \\? \

Вам НЕОБХОДИМО, чтобы ключ реестра HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ FileSystem \ LongPathsEnabled был установлен в 1.

И вам действительно нужно

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
        <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
    </windowsSettings>
</application>

в вашем файле app.manifest.

Кажется, что этот код всегда возвращает 260, даже если включены длинные пути:

FieldInfo maxPathField = typeof(Path).GetField("MaxPath",
                     BindingFlags.Static |
                     BindingFlags.GetField |
                     BindingFlags.NonPublic);

int maxPathLength = (int)maxPathField.GetValue(null);
Console.WriteLine("Max path length is " + maxPathLength);
...