I get a List<string> of files via recursion through FileFinderEx via win32 api (DllImport of kernel32). (There’s several questions that go over how this is done).
I handle fully qualified paths greater than MAX_PATH by using \\?\UNC\ and \\?\.
Also, from win32 api I can grab the “short path” (8.3 name) of file via GetShortPathNameW.
Now that I have the List<string> of fully qualified paths to files, I want to iterate over each path and place their SHA256 into another list (same index). So roughly, something like this:
List<string> files = new List<string>();
//win api function populates files ...
List<string> hash = new List<string>();
for (int i = 0; i < files.Count; i++)
{
using (var stream = new BufferedStream(File.OpenRead(files[i]), 1200000))
{
SHA256Managed sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(stream);
hash.Add(BitConverter.ToString(checksum).Replace("-", String.Empty));
stream.Close();
}
}
The problem I face is even if I give it the “short path” (8.3 name) the File.OpenRead always throws exception if the fully qualified UNC name is greater than MAX_PATH (260 I believe).
So… now what? Is there some win32 api function I can import to do the reading instead of File.OpenRead? Or is there some other .NET method to open files with long file paths? Any tips to get around this limitation?
Take a look at the
CreateFilefunction in kernel32.dll. Despite it’s name, you can use it to either read or create a file, and the Unicode version will allow you to use paths longer thanMAX_PATH.There is a good series of posts (part 1 here) on the BCL Team’s blog from a few years back covering the topic of long paths in Windows and .NET, which I think you’d find useful.