views:

1049

answers:

4

Hi folks,

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"
A: 

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

ck
A: 

Also check out this Mono Options

hth

Sergey Mirvoda
Could you please edit your reply with some same c# code that uses this Mono Options dll, please? Like, how does it read in multiplefiles? what about wildcards? eg. *.txt ??
Pure.Krome
A: 

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).

ShuggyCoUk
+2  A: 

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 :-)

Dan F