.NET 4.6.2 and long paths on Windows 10

The Windows 10 Anniversary update is almost out the door. .NET 4.6.2 is in the update (as we've looked at in the past few posts). I've talked a bit about what we've done in 4.6.2 around paths, and how that is targeted at both allowing access to previously inaccessible paths and opens up the door for long paths when the OS has support. Well, as people have discovered, Windows 10 now has started to open up support. In this post I'll talk about how to enable that support.

Enabling Win32 Long Path Support

Long paths aren't enabled by default yet. You need to set a policy to enable the support. To do this you want to "Edit group policy" in the Start search bar or run "gpedit.msc" from the Run command (Windows-R).

In the Local Group Policy Editor navigate to "Local Computer Policy: Computer Configuration: Administrative Templates: All Settings". In this location you can find "Enable Win32 long paths".

Enabling Win32 long paths in the policy editor.

Enabling Win32 long paths in the policy editor.

After you've turned this on you can fire up a new instance of PowerShell and free yourself from the constraints of MAX_PATH! The key File and Directory Management APIs respect this and now allow you to skip the check for MAX_PATH without having to resort to using "\\?\" (look back to my earlier posts on path formats to understand how this works). This is also possible as PowerShell has opted into the new .NET path support (being that it is a .NET application).

If you look carefully at the description in the setting you'll see "Enabling Win32 long paths will allow manifested win32 applications...". That's the second gate to getting support- your app must have a specific manifest setting. You can see what this is by opening C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe in Visual Studio or some other manifest viewer. Doing so you'll see the following section in it's manifest:

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

These two gates will get you the native (Win32) support for long paths. In a managed app you'll also need the new behavior in .NET. The next section covers this.

Configuring a Simple Long Path .NET Console App

This example uses a new C# Console Application in Visual Studio 2015.

The first thing to do after creating a new console app is edit the App.Config file and add the following after the <startup> end tag:

  <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" />

If you have the 4.6.2 Targeting Pack installed (from the 4.6.2 Developer Pack) you can alternatively select 4.6.2 as your target framework in the project properties instead of using the app.config setting. The defaults for these two values are true if the target framework is 4.6.1 or earlier.

The second thing to do is add the Application Manifest File item to your project. After doing so add the windowsSettings block I shared above. In the default template there is already a commented-out section for windowsSettings, you can uncomment this and add this specific longPathAware setting.

Here is a sample block to add to your Main() method to test it out:

string reallyLongDirectory = @"C:\Test\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
reallyLongDirectory = reallyLongDirectory + @"\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
reallyLongDirectory = reallyLongDirectory + @"\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

Console.WriteLine($"Creating a directory that is {reallyLongDirectory.Length} characters long");

You can open up PowerShell and go and look at the directory you created! Yayyyyyy!

This is the start of what has been a very long journey to remove MAX_PATH constraints. There is still much to do, but now the door is finally open. The rest can and will come- keep your feedback coming in to keep us on track!

The Windows support is documented on MSDN. APIs that aren't listed may work- if the API took \\?\ in the past it will likely support the new behavior.

Note that in this initial release CMD doesn't support long paths. The Shell doesn't add support either, but previously had limited support utilizing 8.3 filename trickery. I'll leave it to the Windows team for any further details.

Comments (54)

  1. T says:

    Looking forward to cmd.exe support for long paths

  2. Hi,

    I don’t really understand why this is not enabled by default in Windows 10 (1607), and also why this has to involve extra configuration set in the application (through the application manifest). Seems to be rather complicated to me.
    Is there any justified cost of enabling it without these extra steps (other than setting the .NET Framework to 4.6.2)?


    1. JeremyKuhne says:

      Because other pieces were not ready (notably CMD) it was felt that off by default was best for the initial release.

      1. Richard Meadows says:

        What is not ready in cmd.exe? Prior to this, I have used cmd.exe as a work around for removing long paths in powershell scripts.

        1. JeremyKuhne says:

          Some limited things work in cmd- there are specific “hacks” to enable people to get out of scenarios like you describe. There are still a number of places where cmd uses fixed size buffers (mkdir for example).

    2. IInspectable says:

      Applications need to opt-in via a manifest, because only the application knows, whether it can support file names longer than MAX_PATH characters. PowerShell does, and contains the appropriate manifest.

      That means, that the group policy cannot be enabled by default, because there’s the possibility of breaking PowerShell scripts, that were written against the documented contract, at a time when the MAX_PATH limit was still there.

      Yes, compatibility is complicated.

  3. TK says:

    Will you reconsider on https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2156195-fix-260-character-file-name-length-limitation?

    The year is 2016 and I just wasted hours today due to a TFS2015 build server that fails in the last “drop” step with “Exception Message: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters. (type PathTooLongException)” in Microsoft.TeamFoundation.Build.Workflow.Activities.WindowsDropProvider.

    An error like this is what I call “classic Microsoft quality”. I appreciate that you are finally doing something about it, but when will it really be solved/solvable?

    It would be great to be able to use just the .NET platform without the Windows legacy, so please keep improving .NET Core. Meanwhile, you have users suffering and getting increasingly annoyed by your decade old bugs.

    1. JeremyKuhne says:

      This is part of fixing that issue. This and the Windows side were key pieces to unblock the rest of the work. Some things can be solved immediately (i.e. PowerShell scripts, opting in custom tools via the config, etc). Because this initial support already solves some problems and allows easier development for the rest of the toolchain pieces we didn’t hold back on other things being finished (CMD for example). Your voices matter in this so please keep the feedback coming and point out your particular fail points (as you have).

      Fyi, .NET Core 1.0 works on any version of the OS with long paths without you needing to do anything. The work here originated in .NET Core- we’re primarily focusing there and pulling back improvements to 4.x where we can (such as this one).

      Incidentally, that issue was reopened as https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/4954037-fix-260-character-file-name-length-limitation. 🙂

  4. Cyber Sinh says:

    Hi, Good news.
    But not all IO .NET API seem to be compatible. If Directory.CreateDirectory() works as expected, File.Move() crashes again with a PathTooLongException… How can we know what .NET API are “long path aware” and what are not?

    1. JeremyKuhne says:

      Can you give me an repro? It should work. Make sure you don’t have any segments over 255 characters- that is a limitation that is part of the NTFS specification (no file system on any platform supports more than that for file/directory names). There should be no APIs that choke on long paths when configured correctly (assuming the OS is enabled)- there are some that don’t work with \\?\ outside of mscorlib, but that is the only known limitation.

      1. Cyber Sinh says:

        Yes, you’re right. I had one segment that exceed 255 caracters in the path.

      2. Cyber Sinh says:

        The PathTooLongException message is confusing when you enable long path support : “The fully qualified file name must be less than 260…” which is not true. Do you plan to adapt the message depending on the context?

        1. JeremyKuhne says:

          Yeah, the exception message isn’t accurate. I’ll look into updating it- hopefully to match what we have in CoreFx.

      3. skSdnW says:

        The policy description is a bit confusing because I don’t know what it means by node. The segment limit comes from the FS and has never been 260. IIRC the segment limit is surfaced as a DWORD to/from Win32 but unless ReFS changed it we are still stuck at 255. My second guess for what it means by node would be something related to reparse points and the object manager but I don’t see how the kernel32 layer where the MAX_PATH limit ends would care about them in this context. Can you explain what they mean by node here?

        1. JeremyKuhne says:

          I hadn’t noticed that, thanks. I have no idea on what they were trying to say by per node. I assume it was a mistake. I’ll let them know.

          You are correct that segment limits are part of file system specifications and have nothing to do with MAX_PATH. There are no file systems in common usage on any OS (Windows, Mac, Unix, etc.) that allow more than 255 for segments. There are a few that allow less (optical media notably). I’m unaware of any limitations where you can’t use the full segment length outside of a wacky max path limitation of 248 in CreateDirectory() that is also removed with the support enabled.

  5. Eugene says:

    I couldn’t create long path directory from your example. Windows 10 Home Build 1607, VS 15 Preview 3.
    The error says “System.IO.DirectoryNotFoundException: Could not find a part of the path”.

    1. JeremyKuhne says:

      You’ll need to give me a concrete example of the path you’re trying to create. It is possible you’re trying to create a path that is getting some part of itself normalized away.

      1. JohnyL says:

        The code was taken right from your example by copy/paste.

        1. JeremyKuhne says:

          I can’t reproduce your error. Validate that you have a correct app.config and app.manifest and that the manifest is inside your .exe (open it in VS to see it) and that you don’t have a standalone .manifest in your output directory that has different settings than the embedded one. Check that the path that you copied didn’t end up with spaces in it. Also, of course, make sure the policy is set and that you’ve restarted VS.

          Other than that you could be colliding with existing paths. Try your own long path(s).

          1. JohnyL says:

            It works! Thanks a lot! 🙂

        2. JohnyL says:

          Home Edition doesn’t have Group Policy Editor. Is there some other way to the the same?

          1. JeremyKuhne says:

            You can set the registry key directly. It’s “\Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\” with the “LongPathsEnabled” DWORD value set to 1.

    2. Prasanth Louis says:

      That’s because you didn’t enable the long path setting in gpedit.msc

  6. Marco Adriani says:

    Great news!
    The behavior of applications not supporting long paths will remain the same with files and folders created by applications that support them?

    1. JeremyKuhne says:

      They will be no different than they used to be when encountering paths that are longer than MAX_PATH. You could always create long paths on Windows if you used the extended device syntax (\\?\), and some frameworks and tools already create files this way. Win32 APIs take a buffer size- you won’t get a path back that is bigger than you specify. In the case of .NET apps they will still throw at MAX_PATH by default.

  7. vp says:

    var longpath = @”c:\temp\”+$”{Guid.NewGuid()}{Guid.NewGuid()}{Guid.NewGuid()}{Guid.NewGuid()}{Guid.NewGuid()}{Guid.NewGuid()}{Guid.NewGuid()}{Guid.NewGuid()}{Guid.NewGuid()}{Guid.NewGuid()}”;

    Directory.CreateDirectory(longpath );

    still see this
    Unhandled Exception: System.IO.PathTooLongException: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
    at System.IO.LongPathHelper.Normalize(String path, UInt32 maxPathLength, Boolean checkInvalidCharacters, Boolean expandShortPaths)

    1. JeremyKuhne says:

      You can’t have segments over 255 characters. See my reply to skSdnW for more details.

  8. Do you have any news about support of long paths in Windows Server 2016? The TechPreview5 hasn’t got the option “enable win32 long paths” and Explorer is not able to manage path longer than 260 characters.

    1. JeremyKuhne says:

      Sorry, I don’t have any info on Server status. Explorer doesn’t handle long paths yet (modulo an existing partial support if it can create a <260 char 8.3 version of the path).

  9. I’ve tested c# code with Win 10 (1607) and works fine. My console app was able to write long paths adding the AppContextSwitchOverrides under . But it was not required to add a manifest. Why? Perhaps I haven’t completely understood you post. Manifest and app.config are two different options for managing long paths or need to be both used on the same app?

    1. JeremyKuhne says:

      It should require the manifest as well, I’ll look to see if I get the same behavior. Basically Windows has two gates, the registry (which you can set via the policy), and each app’s manifest. A normal (e.g. not “\\?\”) long path will fail in Win32 if those aren’t both set. It is possible that there is a bug in the logic, but the documentation requires the manifest setting.

      The app.config thing is specifically for .NET. It is technically a breaking change so if you want the behavior without targeting 4.6.2 you need to explicitly opt in via the app.config. (Or potentially opt out if you are targeting 4.6.2).

      1. Any news about this? Reading your response to MuiBienCarlota, it seems that a manifest file is not required and a modified app.config is enough to turn on the new behavior (on a system with 4.6.2 installed).

  10. I’ve run c# code similar to yours on a “regular” hard-disk and it worked fine. But it failed on a harddisk encrypted with BitLocker. Is it the expected behavior?

    1. JeremyKuhne says:

      I’m not aware of BitLocker specific issues, I’ll give it a try. I’ll let the Windows folks know.

  11. MuiBienCarlota says:

    I’ve Apps targeting .Net 4.6 and I would like to stay with it.
    Is there a way to benefit of long file name support when my Apps runs under .Net 4.6.2 on a properly configured Windows 10 1607 system?

    1. JeremyKuhne says:

      Use the AppContext switches in your .config file as described. That will turn on the behavior if 4.6.2 is installed and your app targets < 4.6.2.

      1. freeAll says:

        Can you get away with not updating windows, only installing .net 4.6.2, but still target and earlier version? Or does this require the latest version of windows 10 and .net 4.6.2 together?

        1. JeremyKuhne says:

          You can use \\?\ with any version of the OS if you have 4.6.2 or higher. Not using \\?\ is a new OS feature. .NET Core supports downlevel without \\?\ by taking care of \\?\ for you.

  12. After installing the .NET Framework 4.6.2 Developer Pack and setting the Enable Win32 long paths, I still cannot create a project in Visual Studio with a long path.

    Did I miss something or does Visual Studio 2015 need to be updated?

    Thank you,


    1. JeremyKuhne says:

      Visual Studio needs updated to support long paths. I know they’re looking at getting it working, just not sure when it will get done. OS progress will be driving it I suspect.

  13. dhananjay shakyawar says:

    Thanks! This helped a lot.

  14. mortb says:

    I’m able to get this to work on my local machine that runs windows 7 (seems to be no need for 10…) and I have created and moved file with very long paths and long file names.
    However it does not seem to work creating a file with a long path on a network share using the syntax \\?\UNC\\ .
    It seems that the max_path limitation is still valid for the network share. Do you know what needs to be in place for this to work on the network share? Does the policy have to be set on the machine that is serving the share or does the server has to be a current version? I querid the win32 api function GetVolumeInformation(…) to get information about that network but that only returns information about how long the path fragments (single dirs and files) may be (255 chars) and not about the maximum total path length of files / directories on the share.

    1. JeremyKuhne says:

      \\?\ has been around forever- you don’t require any sort of setup to use it outside of .NET not supporting it until my changes. Try doing things from the command prompt with \\?\ to see what limitations you have or don’t have. I’m able to using both \\?\UNC\ and \\Server\Share with long paths on Creators Update from CMD when I’ve enabled on both ends.

  15. Michael says:

    I have some questions:

    * Will this feature (not having to use “\\?\” for long paths in my code) work with all Oses supporting .NET 4.6.2, or just Windows 10?
    * After Windows 10’s Creators update, I can no longer use this code without it throwing an ArgumentException (It worked on 4.6.2 before the Creators update):

    DirectoryInfo directoryInfo = new DirectoryInfo(@”\\?\” + “someLongPathHere”);

    Is that a bug?

    1. JeremyKuhne says:

      There was a bug in Anniversary Update (RS1) that long paths would work without the manifest. That was fixed in Creators Update (RS2)- you _need_ the manifest entry.

      1. Cody says:

        I have written a web application that needs to use long paths. With the Anniversary update, the web application worked fine, probably because of the bug that made it so an app.manifest was not required. However, when we updated to the Creators update (RS2), this application started throwing max path exceptions (assuming because the app.manifest bug had been fixed and now an app.manifest is required). From my research, it is not possible to simply add an app.manifest or throw the windows setting into the web.config since there seems to be a fundamental difference between a console application and a web application in this context. Is there any way to satisfy the app.manifest requirement in a web application to get long paths working again?

        1. JeremyKuhne says:

          Unfortunately I’m not aware of one. You might try https://forums.asp.net/. Numerous people have been hit by the manifest “fix”, hopefully we’ll see a fix for the “fix” from Windows. I’ll post if I see such a thing happening.

  16. Good news is this takes care of my DirectoryInfo issue.

    However FileInfo object using GetAccessControl() will fail by throwing exception stating “invalid name” instead of returning the FileSecurity object when the ntfsPath is too big when just using the long path by itself.

    If local path (C:\) I must prefix with @”\\?\”
    If UNC path (\\comp\share) I must reformat the string to be @”\\?\UNC\comp\share”

    Source: https://msdn.microsoft.com/en-us/library/aa365247.aspx

    1. JeremyKuhne says:

      Appears to be a limitation in GetNamedSecurityInfo. Have you tried on the Creators Update (RS2)?

  17. Ivan Tarapov says:

    Hi, Jeremy,

    Thanks for a very useful post!

    Trying to add this to a WPF app. When I run this locally, everything runs like a charm. However, when I deploy my app with ClickOnce, the installer can not launch, throwing an exception:

    + Exception reading manifest from https://XXXX/Application%20Files//.manifest: the manifest may not be valid or the file could not be opened.
    + Parsing and DOM creation of the manifest resulted in error. Following parsing errors were noticed:
    -HRESULT: 0x8007001f
    Start line: 0
    Start column: 0
    Host file:
    + A device attached to the system is not functioning. (Exception from HRESULT: 0x8007001F)

    I just copied my the line you have here into application.manifest file. There’s nothing else in the .manifest file.

    Is it ClickOnce failing to recognize something? Is there a way to achieve this at runtime, without touching the manifest?

    1. JeremyKuhne says:

      Sorry, don’t know much about ClickOnce. :/ Windows 10 requires the manifest to allow using long paths without \\?\. (Note there was a bug in RS1 that didn’t require the manifest.)

      1. Ivan Tarapov says:

        Okay, thanks. Maybe someone reading this will have solved this issue for ClickOnce

        Hopefully, this will be turned on by default one day, without manifest manipulations 🙂

  18. HGH says:

    When is this going to be enabled by default? Next update 2018 maybe?

    1. JeremyKuhne says:

      I don’t know- I would presume not until File Explorer is fully updated for long paths. I do know the Windows teams are continuing to fill in the gaps (cmd got fixed in Creators Update for example) and that they do plan to fix File Explorer. Other underlying APIs are being fixed (such as WinRT and Shell APIs)- hopefully we’ll see some of these foundational pieces in the Fall Creators Update…

Skip to main content