Pure.Krome
Pure.Krome

Reputation: 86937

Trying to read in some command line arguments for a console application

i've got a pretty simple .NET console application. I wish to pass in some command line arguments ... nothing tough there.

Now, the kicker is, i usually have a LIST of items i wish to pass in, for one argument. In this case, a list of files. I'm not sure of the best way to do this.

eg. myapp.exe files=aaa.txt,bbb.txt,ccc.txt 

but what about file names with spaces? Should i comma delimate it?

to make things interesting, i've got other args, which accept single values .. so i'm not sure if i should put all the arg data in double quotes..

eg. myapp.exe files=aaa.txt,bbb.txt formatting=true foo=hello

or

eg myapp.exe files="aaa.txt","bbb.txt" formatting="true" foo="hello"

Upvotes: 1

Views: 2585

Answers (3)

Dan F
Dan F

Reputation: 12052

Probably a bit late for the program you are working on, but here's how you could do it using Mono.Options

static void Main(string[] args)
{
    //let's try this mono.options thing shall we?
    string xapfile = null;
    var files = new List<string>();
    var p = new Mono.Options.OptionSet()
    {
        { "xap=", v => xapfile =v },
        { "file:", v => files.Add(v)}
    };
    List<string> extra = p.Parse(args);


    Console.WriteLine(@"
    xap = '{0}', 
    file(s)= {1}", 
         xapfile, 
         string.Join(",", files.ToArray())
    );
    Console.WriteLine(@"
    left overs: {0}", 
        string.Join(Environment.NewLine, extra.ToArray())
    );
    // rest of your Main here

Calling syntax would be

myapp.exe --file="file 1" --file="file 2" --file="file 3"

You could even forgo the whole files variable and just treat the left overs as the files, and call it like myapp.exe "file 1" "file 2" "file 3" and pluck the files out of the extra list.

Mono.Options is pretty powerful. You don't even have to use --, it appears you can use /file= or -file=

Unfortunately, Windows doesn't do globbing for you (unless you're passing the options to a powershell cmdlet), so you have to do it yourself. It's pretty easy though, here's a bit of code I've used in the past to expand *.foo or "c:\temp\*.bar|c:\temp\*.txt"

Also, unless you wrap the filenames in talkies, I probably wouldn't comma separate the list, as comma is valid in a filename. You know that one is going to bite you one day :-) Pipe makes a good choice, but only if you wrap the whole expression in talkies, otherwise windows thinks you're doing piping. Ah, the joys of command line processing :-)

Upvotes: 2

ShuggyCoUk
ShuggyCoUk

Reputation: 36438

Given that your shell probably supports wild card globbing it is best to allow the input files to be a plain space separated list and to assume that if a file name contains spaces that it will have been escaped already either by surrounding with quotes or via \ characters. By plain I mean contain no --f or /f style switches.

A slightly less common technique, but nor supported by all libraries doing command line parsing, is to allow multiple entries of the form -f foo.txt -f bar.txt. This does not play well with command line globbing (unlike the above solution).

Upvotes: 0

cjk
cjk

Reputation: 46415

Each argument, if it contains any spaces must be enclosed in quotes. Otherwise I would leave quotes out of it.

Upvotes: 0

Related Questions