Best way to resolve file path too long exception

281,933

Solution 1

As the cause of the error is obvious, here's some information that should help you solve the problem:

See this MS article about Naming Files, Paths, and Namespaces

Here's a quote from the link:

Maximum Path Length Limitation In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length for a path is MAX_PATH, which is defined as 260 characters. A local path is structured in the following order: drive letter, colon, backslash, name components separated by backslashes, and a terminating null character. For example, the maximum path on drive D is "D:\some 256-character path string<NUL>" where "<NUL>" represents the invisible terminating null character for the current system codepage. (The characters < > are used here for visual clarity and cannot be part of a valid path string.)

And a few workarounds (taken from the comments):

There are ways to solve the various problems. The basic idea of the solutions listed below is always the same: Reduce the path-length in order to have path-length + name-length < MAX_PATH. You may:

  • Share a subfolder
  • Use the commandline to assign a drive letter by means of SUBST
  • Use AddConnection under VB to assign a drive letter to a path

Solution 2

The solution that worked for me was to edit the registry key to enable long path behaviour, setting the value to 1. This is a new opt-in feature for Windows 10

HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD)

I got this solution from a named section of the article that @james-hill posted.

https://docs.microsoft.com/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

Solution 3

There's a library called Zeta Long Paths that provides a .NET API to work with long paths.

Here's a good article that covers this issue for both .NET and PowerShell: ".NET, PowerShell Path too Long Exception and a .NET PowerShell Robocopy Clone"

Solution 4

You can create a symbolic link with a shorter directory. First open command line for example by Shift + RightClick in your desired folder with a shorter path (you may have to run it as administrator).

Then type with relative or absolute paths:

mklink ShortPath\To\YourLinkedSolution C:\Path\To\Your\Solution /D

And then start the Solution from the shorter path. The advantage here is: You don't have to move anything.

Solution 5

What worked for me is moving my project as it was on the desktop (C:\Users\lachezar.l\Desktop\MyFolder) to (C:\0\MyFolder) which as you can see uses shorter path and reducing it solved the problem.

Share:
281,933
Muhammad Raja
Author by

Muhammad Raja

Microsoft Certified Solution Developer (MCSD): SharePoint Applications Microsoft Certified in followings : TS: Microsoft Office SharePoint 2010, Configuring Programming in HTML5 with JavaScript and CSS3 Developing ASP.NET MVC 4 Web Applications Developing Microsoft SharePoint Server 2013 Core Solutions Developing Microsoft SharePoint Server 2013 Advanced Solutions Blog: http://sharepointbulletin.blogspot.co.uk CodePlex: http://www.codeplex.com/site/users/view/MuhammadRaja LinkedIn: uk.linkedin.com/pub/muhammad-raja/52/541/2ba/ JSFiddle: http://jsfiddle.net/user/muhammadraja/

Updated on January 27, 2022

Comments

  • Muhammad Raja
    Muhammad Raja over 2 years

    I created a app that downloads all document libraries in a SP Site , but at one point it giving me this error (I tried looking at google but couldn;t find anything, now if anyone knows any trick to solve this problem please respond otherwise thanks for looking at it)

    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.Path.NormalizePathFast(String path, Boolean fullCheck) at System.IO.Path.GetFullPathInternal(String path) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at System.IO.File.Create(String path)

    it reaches the limit for string, Code is given below,

    #region Downloading Schemes
    
        private void btnDownload_Click(object sender, EventArgs e)
        {
            TreeNode currentNode = tvWebs.SelectedNode;
            SPObjectData objectData = (SPObjectData)currentNode.Tag;
            try
            {
                CreateLoggingFile();
                using (SPWeb TopLevelWeb = objectData.Web)
                {
                    if(TopLevelWeb != null)
                        dwnEachWeb(TopLevelWeb, TopLevelWeb.Title, tbDirectory.Text);
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(string.Format("Exception caught when tried to pass TopLevelWeb:{1}, Title = {2}, object data to (dwnEachWeb_method), Exception: {0}", ex.ToString(), objectData.Web, objectData.Title));
            }
            finally
            {
                CloseLoggingFile();
            }
        }
    
        private void dwnEachWeb(SPWeb TopLevelWeb, string FolderName, string CurrentDirectory)
        {
            if (TopLevelWeb != null)
            {
                if (TopLevelWeb.Webs != null)
                {
                    CurrentDirectory = CurrentDirectory + "\\" + TopLevelWeb.Title;
                    CreateFolder(CurrentDirectory);
                    foreach (SPWeb ChildWeb in TopLevelWeb.Webs)
                    {
    
                        dwnEachWeb(ChildWeb, ChildWeb.Title, CurrentDirectory);
                        ChildWeb.Dispose();
                    }
                    dwnEachList(TopLevelWeb, CurrentDirectory);
                    //dwnEachList(TopLevelWeb, FolderName, CurrentDirectory);
                }
            }
        }
    
        private void dwnEachList(SPWeb oWeb, string CurrentDirectory)
        {
            foreach (SPList oList in oWeb.Lists)
            {
                if (oList is SPDocumentLibrary && !oList.Hidden)
                {
                    dwnEachFile(oList.RootFolder, CurrentDirectory);
                }
            }
        }
    
        private void dwnEachFile(SPFolder oFolder, string CurrentDirectory)
        {
            if (oFolder.Files.Count != 0)
            {
                CurrentDirectory = CurrentDirectory + "\\" + oFolder.Name;
                CreateFolder(CurrentDirectory);
                foreach (SPFile ofile in oFolder.Files)
                {
                    if (CreateDirectoryStructure(CurrentDirectory, ofile.Url))
                    {
                        var filepath = System.IO.Path.Combine(CurrentDirectory, ofile.Url);
                        byte[] binFile = ofile.OpenBinary();
                        System.IO.FileStream fstream = System.IO.File.Create(filepath);
                        fstream.Write(binFile, 0, binFile.Length);
                        fstream.Close();
                    }
                }
            }
        }
    
        //creating directory where files will be download        
        private bool CreateDirectoryStructure(string baseFolder, string filepath)
        {
            if (!Directory.Exists(baseFolder)) return false;
    
            var paths = filepath.Split('/');
    
            for (var i = 0; i < paths.Length - 1; i++)
            {
                baseFolder = System.IO.Path.Combine(baseFolder, paths[i]);
                Directory.CreateDirectory(baseFolder);
            }
            return true;
        }
    
        //creating folders
        private bool CreateFolder(string CurrentDirectory)
        {
            if (!Directory.Exists(CurrentDirectory))
            {
                Directory.CreateDirectory(CurrentDirectory);
            }
            return true;
        }
    
        //shorting string
    
        #endregion
    
  • James Hill
    James Hill over 12 years
    @TimeToThine, did you read the article that I posted? Did you read the comments? I could be wrong, but I don't think you're going to get any more help from the SO community, other than what I've already provided.
  • Muhammad Raja
    Muhammad Raja over 12 years
    Yes I already read that before posting my question here, I even tried "\\?\" but for some reason its not working in this context. I find this blog, using it but for some reason its not working properly, "codinghorror.com/blog/2006/08/shortening-long-file-paths.ht‌​ml" Am still looking for something that keeps the directory saved and i can take it from there, or something like that, forexample use a hidden label to save the current directory instead of string, but not sure if it will gonna work.
  • Arthur
    Arthur almost 8 years
    Now this is just wonderful, and really easy to update the code for using it. Thanks.
  • Jaider
    Jaider over 7 years
    It is obvious but it doesn't make any sense. Why is there a path-size limitation??? it is 2017.
  • Adam Lindsay
    Adam Lindsay about 7 years
    If I changed the current directory to the directory of the folder using Directory.SetCurrentDirectory() would it avoid this restriction. Or would the problem still exist.
  • N-ate
    N-ate about 6 years
    This doesn't work in VS2015. It would appear that VS is prevalidating the length of the path. See N-Ate answer for VS2015 work-around.
  • Tom Deblauwe
    Tom Deblauwe about 6 years
    The article seems to have been updated: Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions. But you must opt-in, and set a registry key to enable it.
  • samus
    samus almost 6 years
    After re-opening properties when my build failed I noticed the new path "c:\vs\bin\Release" was substituted as "..\..\..\..\..\..\..\..\vs\bin\Release\". I'm not sure if "..\" gets factored into character count.
  • N-ate
    N-ate almost 6 years
    Paths that are evaluated as too long are absolute paths.
  • RoLYroLLs
    RoLYroLLs almost 6 years
    This solution seems to still work. tested on VS2017 v15.7.6
  • Filipe Calasans
    Filipe Calasans almost 6 years
    What you can do is to map the solution folder to a driver using the command "subst". That works for VS2017.
  • Losbear
    Losbear over 5 years
    Additional info for anyone who reads this - Filenames are limited to 247 characters while the full path is limited to 259. So if your filename is 239, that only leaves 20 characters for the rest of the path (eg "c:\temp"). If you trim the filename, you need to make sure the FULL path is 259 characters or less.
  • Mr Angry
    Mr Angry over 4 years
    I've got this set to 1 and still getting the error, no idea why at this point.
  • Tom Anderson
    Tom Anderson over 4 years
    The article mentions two requirements. Firstly the registry key, and secondly the application xml: <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="https://schemas.microsoft.com/SMI/2016/WindowsSet‌​tings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application> For me in Visual Studio 2019, this second requirement was not necessary after restarting Visual Studio.
  • Ondra Starenko
    Ondra Starenko over 4 years
    I'm sorry probably this is stupid question but What is "application xml"? Is it web.config or something else? I have this problem on Web Page asp.net project
  • Zoman
    Zoman over 4 years
    As said above, it works fine in Visual Studio 2019 (after restart) without changing the application xml. Thanks for the solution.
  • Sharad
    Sharad about 4 years
    @TomAnderson : I am using VS2017. Where iI can find this application.xml ? as after doing 1st step does not solve my problem.
  • Shiva
    Shiva over 3 years
    @OndraStarenko The xml is in the application manifest file. See Application Manifests for more info. You'll need to add the longPathAware to your application's manifest file. For example, If you open PowerShell.exe from your C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe in Visual Studio, you can view the application manifest. And see this setting inside the exe.
  • dontbyteme
    dontbyteme over 3 years
    Link to further details mentioned by Tom Anderson: docs.microsoft.com/de-de/windows/win32/fileio/…
  • Vinícius Matos
    Vinícius Matos over 2 years
    Much simpler and more objective. Thanks!