This is a continuation of a previous problem I had with a "dir" like program. The previous solution actually *doesn't* work as I'd hoped. the Path class works, as far as I can tell, when the paramater is passed in a very specific way. It doesn't work if I don't have a specific volume, directory, and filename listed. For example, if I just use "..\*.exe", it will recognize that the "directory" is .., and the filename is *.exe... but it will not infer the volume since it is not listed in the paramater.

This is my code so far.

static void Main(string[] args) {

            string exeName = Environment.CommandLine.Remove(Environment.CommandLine.IndexOf(".exe"));
            string workingDirectory = "";
            string fileSearchString = "";
            DirectoryInfo[] dirList;
            FileInfo[] fileList;
            switch (args.Length) {
                case 0:
                    workingDirectory = Environment.CurrentDirectory;
                    fileSearchString = "*.*";
                case 1:
                    workingDirectory = args[0];
                    Console.WriteLine("The syntax of the command is incorrect.");
                    Console.WriteLine("Usage: {0} [drive:][path][filename]", exeName);

            DirectoryInfo currentDir = new DirectoryInfo(workingDirectory);

            dirList = currentDir.GetDirectories();
            fileList = currentDir.GetFiles(fileSearchString);

            foreach (DirectoryInfo dir in dirList)
                Console.WriteLine("Directory: {0}", dir);
            foreach (FileInfo file in fileList)
                Console.WriteLine("File: {0}", file);

Basically, what I want to happen, is when the program is run without any arguments, the argument "*.*" is assumed. This has been accomplished as far as I can tell. If the program has more than one argument, it generates an error stating that the program is not being used properly, which also has been done. The problem I am having is in parsing the single parameter that is passed. I want it to be able to recognize and split the various parts of a possible string.

For example, any of the following (and many more) may be passed as a valid parameter:

  • *.ext
  • file*.ext
  • *file.ext
  • path\file.ext
  • ..\file.ext
  • ..\*.ext
  • volume:\path\file.ext

If I run the program as-is with the paramater "..\" it works fine, because that is a valid path. but if I run the program with the paramater "*.*" or even "..\*.*", I get "System.ArgumentException: Illegal characters in path." I need to be able to separate the "..\" as the workingDirectory and the "*.*" as the fileSearchString. And not to mention, if there is *also* a volume in front of the path, I need to get that too.

I hope you get the point. What I need is to parse out the volume (if it exists - otherwise use current), the directory (if it exists) and the file search pattern (exact filename or wildcard). How should I go about writing the code for my switch case of "1"?

Path.GetFullPath("..\"); works, returning the fully qualified path starting with the C:\ (based on the current working dir), but if I do Path.GetFullPath("..\*.*"); it fails, saying that there are invalid characters in the path.

Here is a bit more information I found out:

if I use this code in my case 1: block it *sorta* works, but not as expected in all cases...

workingDirectory = Path.GetDirectoryName(args[0]);
                    fileSearchString = Path.GetFileName(args[0]);

I also have to add this below my switch statement

if (workingDirectory == null)
                workingDirectory = Path.GetFullPath(args[0]);
            if (fileSearchString == null)
                fileSearchString = "*.*";

The problem with this, is if I use the argument "c:\Games", it acts as if I only typed "c:\".. if I add a trailing slash to the end, it works, as it recognizes that "Games\" is the path and not the filename. If I use ".." as the paramater, I get "System.ArgumentException: The path is not of a legal form."

There's just so many forms that *should* work, or at least I need them to work, but they generate errors.

You would think that MS would have added all of this Parsing to Volume/Path/Filename class by now, but I guess they don't want to piss off some of their partner's value added resales of libraries or something. Anyway, I would resort to searching existing code available at CodeProject or something. This stuff is like reinventing the wheel many times over in its fundamental IO statistics/demographics/structure.
Anyway, here is what I got from a relative path for your volume info request using "..\*.*":

Console.WriteLine(Directory.GetDirectoryRoot(args[0])); // returns volume as "C:\"

good luck.

maybe a regexp would work, but I can't think of how to build it.. I start off with ([A-Za-z\:]{0,2}) to recognize the volume, but from there I have no idea.. I don't even know if that would work. the "volume" should match either a letter followed by a :, or a starting \.