GetDirectories throws PathTooLongException

M

mjheitland

When I pass my directories recursively on a directory structure with
paths > 260 chars I get the following exception (see line marked with
***), although I am using only ShortPathNames through Win32API
function::

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.

My short path names are < 255 characters, but internally .NET calls
GetFullPathInternal() within Directory.GetDirectories().

I tried to use Unicode-Escape characters @"\\?\" as the following link
suggested, but it did not work:
<http://aspadvice.com/blogs/davidwalker/archive/2007/01/22/
PathTooLongException-work-around.aspx>
Are Unicode paths (which allow us to have paths up to 32.000 chars)
differently escaped in .NET?

Is there another API to get the full path > 260 chars?

int CountFilesInDirectory(BackgroundWorker backgroundWorker,
DoWorkEventArgs e, string startDirectoryLongForm, string
startDirectoryShortForm)
{
try
{
if (backgroundWorker != null &&
backgroundWorker.CancellationPending)
{
e.Cancel = true;
return 0;
}

int numFiles = 0;
//*** startDirectoryShortForm = ""D:\\MG0704\\EINSEH~1\\EINSEH~1\
\EINSEH~1\\EINSEH~1\\"";
//*** startDirectoryLongForm = ""D:\\MG0704\\Ein sehr langer
Verzeichnisname 0123456789 0123456789 0123456789 0123456789
0123456789 0123456789 0123456789 0123456789 0123456789 0123456789
0123456789 0123456789Ein sehr langer VerzeichnisnameEin sehr langer
VerzeichnisnameEin sehr langer Verzeichnisname""
foreach (string directoryMixedForm in
Directory.GetDirectories(startDirectoryShortForm)) // *** here the
PathTooLongException is thrown
{
string directoryLongForm = startDirectoryLongForm +
Path.GetFileName(directoryMixedForm);
string directoryShortForm =
PathConverter.ToShortPathName(directoryMixedForm);
numFiles += CountFilesInDirectory(backgroundWorker, e,
directoryLongForm, directoryShortForm);
if (e.Cancel || (backgroundWorker != null &&
backgroundWorker.CancellationPending))
{
return 0;
}
}

int numFilesInThisDirectory =
Directory.GetFiles(startDirectoryShortForm).Length;
if (numFilesInThisDirectory > 0)
{
OnNonEmptyFolderEntered(new
NonEmptyFolderEnteredEventArgs(startDirectoryLongForm));
if (startDirectoryShortForm.Length >
_longestPathWithoutFileNameShortForm.Length)
{
_longestPathWithoutFileNameShortForm =
startDirectoryShortForm;
}
}

return numFiles + numFilesInThisDirectory;
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
return 0;
}
}

/*
Maximum for path names is 260 (including drive and terminating '\0':
*/
using System;
using System.Text;
using System.Runtime.InteropServices;

namespace ProofPoolCreator
{
/// <summary>
/// Converts file and directory paths to their respective
/// long and short name versions.
/// </summary>
/// <remarks>This class uses InteropServices to call GetLongPathName
and GetShortPathName</remarks>
static class PathConverter
{
[DllImport("kernel32.dll")]
static extern uint GetLongPathName(
string shortname,
[Out] StringBuilder longnamebuff,
uint buffersize);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern uint GetShortPathName(
[MarshalAs(UnmanagedType.LPTStr)]
string path,
[MarshalAs(UnmanagedType.LPTStr)]
StringBuilder shortPath,
uint shortPathLength);

/// <summary>
/// The ToShortPathNameToLongPathName function retrieves the long
path form of a specified short input path
/// </summary>
/// <param name="shortName">The short name path</param>
/// <returns>A long name path string</returns>
public static string ToLongPathName(string shortName)
{
StringBuilder longNameBuffer = new StringBuilder(260);
uint bufferSize = (uint) longNameBuffer.Capacity;

GetLongPathName(shortName, longNameBuffer, bufferSize);
string longName = longNameBuffer.ToString();
return AppendPathSeparator(longName);
}

/// <summary>
/// The ToLongPathNameToShortPathName function retrieves the short
path form of a specified long input path
/// </summary>
/// <param name="longName">The long name path</param>
/// <returns>A short name path string</returns>
public static string ToShortPathName(string longName)
{
StringBuilder shortNameBuffer = new StringBuilder(260);
uint bufferSize = (uint) shortNameBuffer.Capacity;

GetShortPathName(longName, shortNameBuffer, bufferSize);
string shortName = shortNameBuffer.ToString();
return AppendPathSeparator(shortName);
}

public static string AppendPathSeparator(string path)
{
if (!path.EndsWith("\\") && !path.EndsWith("/"))
{
return path + '\\';
}
else
{
return path;
}
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top