Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting actual file name (with proper casing) on Windows with .NET

Tags:

.net

windows

I want to do exactly the same as in this question:

Windows file system is case insensitive. How, given a file/folder name (e.g. "somefile"), I get the actual name of that file/folder (e.g. it should return "SomeFile" if Explorer displays it so)?

But I need to do it in .NET and I want the full path (D:/Temp/Foobar.xml and not just Foobar.xml).

I see that FullName on the FileInfo class doesn't do the trick.

like image 562
pauldoo Avatar asked Nov 28 '08 14:11

pauldoo


People also ask

Can Windows filenames have colons?

On Windows systems, files and directory names cannot be created with a colon (:). But if a file or directory name is created with a colon on a Linux or Mac operating system, then moved to a Windows system, percent encoding is used to include the colon in the name in the index.

How are files named in Windows?

Under Windows, this 8.3 name is automatically assigned by the operating system in the background whenever you save a file with a long file name. It usually consists of the first six letters of the long file name, a tilde (~), and a sequential number so that it is unique.


1 Answers

I seems that since NTFS is case insensitive it will always accept your input correctly regardless if the name is cased right.

The only way to get the correct path name seems to find the file like John Sibly suggested.

I created a method that will take a path (folder or file) and return the correctly cased version of it (for the entire path):

    public static string GetExactPathName(string pathName)     {         if (!(File.Exists(pathName) || Directory.Exists(pathName)))             return pathName;          var di = new DirectoryInfo(pathName);          if (di.Parent != null) {             return Path.Combine(                 GetExactPathName(di.Parent.FullName),                  di.Parent.GetFileSystemInfos(di.Name)[0].Name);         } else {             return di.Name.ToUpper();         }     } 

Here are some test cases that worked on my machine:

    static void Main(string[] args)     {         string file1 = @"c:\documents and settings\administrator\ntuser.dat";         string file2 = @"c:\pagefile.sys";         string file3 = @"c:\windows\system32\cmd.exe";         string file4 = @"c:\program files\common files";         string file5 = @"ddd";          Console.WriteLine(GetExactPathName(file1));         Console.WriteLine(GetExactPathName(file2));         Console.WriteLine(GetExactPathName(file3));         Console.WriteLine(GetExactPathName(file4));         Console.WriteLine(GetExactPathName(file5));          Console.ReadLine();     } 

The method will return the supplied value if the file does not exists.

There might be faster methods (this uses recursion) but I'm not sure if there are any obvious ways to do it.

like image 160
Yona Avatar answered Sep 20 '22 08:09

Yona