Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canonical solution for escaping .NET command line arguments

Question: Given a file name and an arbitrary list of strings, is there a canonical way to create a single command line such that Environment.GetCommandLineArgs (and C#'s void main(String[] args)/ VB's Sub Main(args() As String)) will return the same list of strings?


Background: The way .NET splits a command line into arguments is surprisingly complex, e.g.:

If a double quotation mark follows two or an even number of backslashes, each proceeding backslash pair is replaced with one backslash and the double quotation mark is removed. If a double quotation mark follows an odd number of backslashes, including just one, each preceding pair is replaced with one backslash and the remaining backslash is removed; however, in this case the double quotation mark is not removed.

Many try the simple "put every argument in double quotes and escape existing double quotes" approach and fail as soon as one of the arguments contains a trailing backslash. There have been various questions on StackOverflow regarding this issue, e.g.:

  • How to escape path containing spaces
  • Escape command line arguments in c#
  • Escape string for Process.Start
  • Passing command-line arguments in C#

However, their answers are either not general enough to provide a canonical solution for all cases or appear to be developed "iteratively" ("Oh, there's one more special case I forgot, let's add it and now it should cover most cases..."). Since this is quite a common problem, I'd like to see a solution that provides confidence, for example, by either

  • coming from an authoritative source (maybe a blog entry from one of the developers involved in this crazy command line convention) or
  • providing a formal proof that the given algorithm satisfies the .NET command line requirements.
like image 482
Heinzi Avatar asked Dec 10 '12 07:12

Heinzi


People also ask

How do you separate command line arguments?

Each argument on the command line is separated by one or more spaces, and the operating system places each argument directly into its own null-terminated string. The second parameter passed to main() is an array of pointers to the character strings containing each argument (char *argv[]).

What are command line arguments stored as?

Only string values can be passed as command line arguments. All the command line arguments are stored in a character pointer array called argv[ ]. Total count of command line arguments including file path argument is stored in a integer parameter called argc.


2 Answers

This algorithm is generic and comes from a relatively authoritative source (MSDN blogs).

like image 189
Anton Tykhyy Avatar answered Sep 29 '22 11:09

Anton Tykhyy


A few years ago, Microsoft announced that they were going to release a command line parser on CodePlex (instead of the System.Shell.CommandLine that was supposed to ship with .NET Framework 4). I'm not sure if they actually did this. If you want a parser developed by a Microsoft employee have a look at cmdline. Also you can look for command line parses in CodePlex.

You could also try Mono.Options which is quite powerful.

like image 29
Panos Rontogiannis Avatar answered Sep 29 '22 12:09

Panos Rontogiannis