PathTooLongException work around

Published 22 January 07 12:01 AM | dwalker 

Someone just came to me with an issue they were having with a classic ASP application that is using the FileSystemObject to display files as links.

Everything was working great, until all of the sudden some files were not showing up. Come to find out, the root cause was due to the fact that the FileSystemObject, just like Windows Explorer, is limited to a MAX_PATH of 260 characters for any full path and file name. Since there was already error handling (and hiding) in the Classic ASP code, this was not obvious at first. What really made it very obvious was when Windows Explorer wouldn't allow a file to be renamed past the 260 character limit.

Windows Vista Ultimate RTM - Windows Explorer has the same limitation.

The files that were exceeding this limit had been copied to this location via an automated Robocopy.

I whipped up a proof of concept .NET ASPX WebForm using DirectoryInfo - GetFileSystemInfos(). But alas, with this method it was generating the following exception:

Exception Details: System.IO.PathTooLongException: The path is too long after being fully qualified. Make sure path is less than 260 characters.

After further research, the only solution I discovered was to use the Windows API via PInvoke of CreatFileEx. This API utilizes unicode for the path and can handle up to 32,000 characters. Supposedly appending the string "\\?\" in front of the path should force that path to be sent as unicode, but I was unable to get this to work successfully. Instead, this was causing an invalid character exception. I will continue looking at this alternative considering the preformance improvements that would come along with it. It's just a matter of getting the unicode part working, here's a resource I discovered that showed some VB.NET code - http://vbnet.mvps.org/index.html?code/fileapi/fsoapicompare.htm.

After more trial and error on my own, I did finally discover the easiest work around and that is to simply use these two methods of the .NET framework instead:

System.IO.Directory.GetFiles()

System.IO.Directory.GetDirectories()

They both return back string arrays of the full path of the files and directories respectfully. As long as you don't need the additional properties, as in this case, this is the easiest solution to the problem.

Sponsor
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# mabra said on August 6, 2008 8:47 AM:
Hi ! Your note about the methods of the framwork are wrong: System.IO.Directory.GetFiles() System.IO.Directory.GetDirectories() Both throw "path too log exception" in a test I made. I would like to see a sample using the Windows API from C# ;-) --mabra
# dwalker said on August 12, 2008 10:18 PM:

Okay Mabra. Just for you and because when called out I feel the urge to prove it. :)

Here's an example with all the code you need. Simply create a new Web Application and place a Literal called DirectoryLiteral. Then, in the code behind for Default.aspx put the following code:

protected void Page_Load(object sender, EventArgs e)
       {
           string path = Server.MapPath(".");
           if (Request.QueryString["path"] != null)
           {
               path = Request.QueryString["path"].ToString();
           }
           DirectoryLiteral.Text = LoadData(path);
       }

       private string LoadData(string path)
       {
           StringBuilder sb = new StringBuilder();
           sb.Append("<ol>");
           if (path.Length > 3)
           {
               string parent = System.IO.Directory.GetParent(path).ToString();
               sb.Append("<li><a href=\"?path=" + parent + "\">..</a></li>");
           }
           foreach (string directory in System.IO.Directory.GetDirectories(path))
           {
               sb.Append("<li><a href=\"?path=" + directory + "\">" + GetDisplayName(directory) + "</a></li>");
           }
           foreach (string directory in System.IO.Directory.GetFiles(path))
           {
               sb.Append("<li>" + GetDisplayName(directory) + "</li>");
           }
           sb.Append("</ol>");
           return sb.ToString();
       }

       private string GetDisplayName(string name)
       {
           int lastSlash = name.LastIndexOf('\\');
           if (lastSlash > 0)
           {
               ++lastSlash;
               name = name.Substring(lastSlash, name.Length - lastSlash);
           }
           return name;
       }

Now create a folder with a really long name, something like:

ReallyLongFolderNameThatWouldCausePathTooLongExceptionWindowsExplorerDoesntEvenSupportFoldersLongerThan260CharactersItStopsAndDoesntLetYouMakeAFolderNamedThatLongOnceYouReachThatManyCharactersInWindowsXPandVista

You will know when it's long enough (based on path where you created your WebApplication and what you named it), because Windows Explorer will not let you exceed 260 characters.

Remove a few back from 260, so that you can go into the folder and create a text file with a name PathTooLongException.txt. Don't worry, again Windows Explorer will not let the full path of the file and it's filename exceed 260 characters.

Once you've created the file, now go back and increase the name of the Folder (it doesn't / can't check the length of the files in the folder at this point). Once you've increased the length of the folder, the file inside the folder will have a full path that exceeds the 260 character limit.

This code will still work and retrieve it's full path and filename, where as, most other API's fail with the Path Too Long Exception.

I couldn't post the original code, since it was for a client I was a consultant with at the time. Since I no longer had the code and was called out, I went ahead and typed it up again real quick.

Let me know if you have any other questions or if someone has the time and a chance to test this issue with Windows Server 2008. My gut says it will exhibit the same behavior, since it's so similar to Windows Vista. I will be excited to learn when Windows OS and Windows Explorer fix this issue. Let us know if/when you find the issue resolved.

# dleo said on August 20, 2008 5:14 PM:
Do you know how to programmatically rename the file so that it is no longer greater than max_path? I have developed all the code that locates the files but can not figure out how to rename/fix the file name. Suggestions?
# dwalker said on September 4, 2008 6:40 PM:

HI dleo,

The easiest way to resolve this would be to move the file to a \\temp folder. Otherwise, there are several things to consider when trying to programmatically rename a file in this regard. Does the actual full path already exceed the max_path of (260 characters)? If so, you will not be able to rename the file at all and instead will have to rename the folder first, then the file. That's why I recommend moving it.

I would recommend simply reporting it and manually handle the situation. The solution could be as simple as just renaming a parent folder, etc.

Leave a Comment

(required) 
(optional)
(required) 
Enter the code you see below

About dwalker

David Walker has over 15 years experience in application development with over 50% of that employed as a consultant with companies such as: Texaco, Bank of Oklahoma, Winner Communications (ESPN.com) and IBM Global Services. At the age of 14, he began his application development ambitions with a Commodore 64, BASIC, and a 300 baud modem. Even at that early age, he primarily focused on two specific application types: multi-user communities and database applications.

His hunger to learn as much as possible about development lead him through courses such as DBase III, DBase IV, Pascal, C, C++, Java, and several in UNIX. He started his development career first doing heavy processing with Access and VBA, then moved on to VB 3, Oracle, and Delphi. Visual Basic was one environment that remained constant for many years, including his very first .NET projects performed in Visual Basic.NET.

After working several years on very high end internal Corporate applications, the consultant company he was working for, sought out his ideas for actual software products that could be packaged and sold. He had already developed several prototypes of a dynamic portal application, before portals even became popular, so this became the logic decision and he became the Director of Product Development. Under his direction, a team of developers and graphic artists, took a skinning approach before that become popular, and completed the core portal application, and continued on to developer 15+ add-on modules, including things such as: Help Desk Ticket Systems, Change Control, Records Management, Human Resources, and many more applications. Eventually, it spun off into it's own separate company as KnowledgeGEAR, a complete intranet in the box solution.

Having worked as a consultant, he has had a experience with a very wide range of applications and architectures, at one time, even converting several Fox Pro and GW-Basic applications to VB 6 and ASP. His early training of Unix and the C language and years of experience with JavaScript, lead him very quickly to C#, where he has remained focused ever since.

He is the current President of the Tulsa Developers .NET user group.. He has been an MCP since 2003 and MCAD and MCSD since 2005. He is currently pursuing his MCDBA and then on to MCSE.

Search

Go

This Blog

Tags

Archives

My Blog Roll (Partial)

My Sites

Syndication