public static string ShortenPathname(string pathname, int maxLength)
{
if (pathname.Length <= maxLength)
return pathname;
string root = Path.GetPathRoot(pathname);
if (root.Length > 3)
root += Path.DirectorySeparatorChar;
string[] elements = pathname.Substring(root.Length).Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
int filenameIndex = elements.GetLength(0) - 1;
if (elements.GetLength(0) == 1) // pathname is just a root and filename
{
if (elements[0].Length > 5) // long enough to shorten
{
// if path is a UNC path, root may be rather long
if (root.Length + 6 >= maxLength)
{
return root + elements[0].Substring(0, 3) + "...";
}
else
{
return pathname.Substring(0, maxLength - 3) + "...";
}
}
}
else if ((root.Length + 4 + elements[filenameIndex].Length) > maxLength) // pathname is just a root and filename
{
root += "...\\";
int len = elements[filenameIndex].Length;
if (len < 6)
return root + elements[filenameIndex];
if ((root.Length + 6) >= maxLength)
{
len = 3;
}
else
{
len = maxLength - root.Length - 3;
}
return root + elements[filenameIndex].Substring(0, len) + "...";
}
else if (elements.GetLength(0) == 2)
{
return root + "...\\" + elements[1];
}
else
{
int len = 0;
int begin = 0;
for (int i = 0; i < filenameIndex; i++)
{
if (elements[i].Length > len)
{
begin = i;
len = elements[i].Length;
}
}
int totalLength = pathname.Length - len + 3;
int end = begin + 1;
while (totalLength > maxLength)
{
if (begin > 0)
totalLength -= elements[--begin].Length - 1;
if (totalLength <= maxLength)
break;
if (end < filenameIndex)
totalLength -= elements[++end].Length - 1;
if (begin == 0 && end == filenameIndex)
break;
}
// assemble final string
for (int i = 0; i < begin; i++)
{
root += elements[i] + '\\';
}
root += "...\\";
for (int i = end; i < filenameIndex; i++)
{
root += elements[i] + '\\';
}
return root + elements[filenameIndex];
}
return pathname;
}