Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't .NET detect directories with long file paths?

I can't enumerate the contained files in a directory if the full path to those files exceeds 260 chars. The following code shows the problem:

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

My app.manifest file contains:

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

But all that did was change the error from PathTooLongException to DirectoryNotFoundException.

Here's my 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>

I'm on Windows 10 Pro, using Visual Studio 2019 16.1.1. I'm targeting .NET 4.7.2.

How can I enumerate files in these overlong directories? They're on a shared network drive that I don't have control over, so renaming the directories is not an option for me.

like image 271
Ebonair Avatar asked Nov 07 '22 16:11

Ebonair


1 Answers

I've got it solved using information from here: What is the maximum amount of characters or length for a Directory?

For .NET 4.6.2 or later: "Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" in App.Config has no effect.

You don't need to prefix paths with \\?\

You DO need the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled set to 1.

And you DO need

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

in your app.manifest file.

This code always seems to return 260, even when long paths are enabled:

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);
like image 177
Ebonair Avatar answered Nov 14 '22 22:11

Ebonair