Getting a files path with capitals included

Came across a post on the Microsoft forum which was looking to find out whether there was a way to get the Path of a file or folder on disk including all the capital letters. Incase you didnt know, the FileInfo and DirectoryInfo use the string you pass in to get them as the FullName property and dont actually check the file on disk at all until you call a function like Exists() which requires them too.
I couldnt see a framework based way to do this so I made this little class to do it. It has a static method you can pass a file or folder path and it will return the path with the case.
Feel free to use it, but please, let me know what you think.
 
public class FileNameGetter
{
[
Serializable,
System.Runtime.InteropServices.
StructLayout
(System.Runtime.InteropServices.LayoutKind.Sequential,
CharSet = System.Runtime.InteropServices.
CharSet.Auto
),
System.Runtime.InteropServices.
BestFitMapping(false)]
private struct WIN32_FIND_DATA
{
public int dwFileAttributes;
public int ftCreationTime_dwLowDateTime;
public int ftCreationTime_dwHighDateTime;
public int ftLastAccessTime_dwLowDateTime;
public int ftLastAccessTime_dwHighDateTime;
public int ftLastWriteTime_dwLowDateTime;
public int ftLastWriteTime_dwHighDateTime;
public int nFileSizeHigh;
public int nFileSizeLow;
public int dwReserved0;
public int dwReserved1;
[System.Runtime.InteropServices.
MarshalAs
(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst = 260)]
public string cFileName;
[System.Runtime.InteropServices.
MarshalAs
(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst = 14)]
public string cAlternateFileName;
}
 
[System.Runtime.InteropServices.
DllImport
("kernel32.dll",
CharSet = System.Runtime.InteropServices.
CharSet.Auto,
SetLastError =
true)]
private static extern IntPtr FindFirstFile(string pFileName, ref WIN32_FIND_DATA pFindFileData);
[System.Runtime.InteropServices.
DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FindClose(IntPtr hndFindFile);
 
public static string GetCasedFilePath(string fullPath)
{
bool isFile = File.Exists(fullPath);
bool isDir = Directory.Exists(fullPath);
if (isDir && !fullPath.EndsWith("\\")) fullPath += "\\";
if ( !isFile && !isDir) throw new FileNotFoundException("File doesnt exist");
string pathbit = fullPath;

Stack<string> pathStack = new Stack<string>();
string dirName = Path.GetDirectoryName(pathbit);
while (dirName != null)
{
pathStack.Push(dirName);
dirName =
Path.GetDirectoryName(dirName);
}
string realPath = string.Empty;
WIN32_FIND_DATA data = new WIN32_FIND_DATA();
while (pathStack.Count > 0)
{
dirName = pathStack.Pop();
if (Path.GetPathRoot(dirName) == dirName)
{
realPath = dirName;
}
else
{
IntPtr findHandle = FindFirstFile(dirName, ref data);
realPath =
Path.Combine(realPath, data.cFileName);
FindClose(findHandle);
}
}
if (isFile)
{
IntPtr findHandle = FindFirstFile(fullPath, ref data);
realPath =
Path.Combine(realPath, data.cFileName);
FindClose(findHandle);
}

return realPath;
}
}

Advertisements
This entry was posted in Uncategorized, Utility and tagged , . Bookmark the permalink.

One Response to Getting a files path with capitals included

  1. Unknown says:

    Works great, although on my machine (I\’m developing on Server 2008 Enterprise), it actually runs about twice as slow as Directory.GetFiles(Path.GetDirectoryName(_path), Path.GetFileName(_path)).First<string>(), but that may be affected by the services I have running. I\’ll have to test it in some other environments to see how the performace compares.
     

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s