Fast Directory Listing using Shell ( DIR )

180 views Asked by At

I'm doing some work to optimise listing the contents of a Folder across a network drive in C#, file and folders. For files I need the FileName, File Size and DateModified, for folders just the Name and DateModified.

I've searched on StackOverflow for various solutions and settled on using Directory.GetFiles, there's no benefit in using EnumerateFiles as I'm not processing the files in parallel.

With my test case over the WAN with 4000 and 5 sub folders GetFiles can still take 30 seconds or more, yet Windows can DIR the folder in 2 seconds.

I don't want to get into too much Windows API code, so I thought a good middle ground would be Shell out the DIR command, redirect the standard output and parse the input. Not pretty, but should be OK. I found this code which does pretty much what I want:

Process process = new Process();
process.StartInfo.FileName = "ipconfig.exe";        
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;        
process.Start();

// Synchronously read the standard output of the spawned process. 
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();

This works fine for ipconfig.exe, but DIR isn't an exe, so any ideas how I might call it? I want to redirect something like this:

DIR "\MyNasDrive\MyFolder"

Worst case I could wrap this up in a .bat file, but that feels fairly horrible.

Any ideas appreciated.

== Found my own solution, but if you can see anything wrong with it please let me know ==

string DirPath = "\\\\MYServer\\MyShare\\";

Process process = new Process();
process.StartInfo.FileName = "C:\\Windows\\System32\\cmd.exe";
process.StartInfo.Arguments = "/C DIR /-C \"" + DirPath + "\"";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.CreateNoWindow = true;
process.Start();

// Synchronously read the standard output of the spawned process. Note we aren't reading the standard err, as reading both
// Syncronously can cause deadlocks. https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.110).aspx
//if we need to do this in the future then might be able to use https://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline(v=vs.110).aspx
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();

process.WaitForExit();
process.Close();
1

There are 1 answers

0
Alexandre Fenyo On

DIR isn't an exe

cmd.exe is an exe.

Call cmd.exe with 2 parameters:

  • /C
  • dir

Note: you could also set UseShellExecute to true.