[.NET Gotcha] Commandline args ending in \" are subject to CommandLineToArgvW whackiness - Jon Galloway

[.NET Gotcha] Commandline args ending in \" are subject to CommandLineToArgvW whackiness

I recently posted on my confusion when I tried to use commandline arguments ending in \" and got unpredictable results. It seemed that all backslashes before a double quote character needed to be escaped, but if they didn't preceed a doublequote, they didn't need to be escaped.

There's more explanation on the original blog post, but here's a summary:

To pass \\this is a test\\ to a console application, you need to pass in \\this is a test\\\\. The first set of backslashes don't require escaping, but the second set do. Stranger still, adding another backslash to that second set has no effect at all doesn't add a backslash, but adds a doublequote: \\this is a test\\\\\ (with 5 backslashes) yields \\this is a test\\". [thanks for correcting me, Carlos].

Via a comment thread on Raymond Chen's blog, I got some help from Carlos:

"Most apps (including .Net apps) use CommandLineToArgvW to decode their command lines.  It uses crazy escaping rules which explain the behaviour you're seeing."

The explanation on MSDN:

CommandLineToArgvW has a special interpretation of backslash characters when they are followed by a quotation mark character ("), as follows:

  • 2n backslashes followed by a quotation mark produce n backslashes followed by a quotation mark.
  • (2n) + 1 backslashes followed by a quotation mark again produce n backslashes followed by a quotation mark.
  • n backslashes not followed by a quotation mark simply produce n backslashes.

I prefer Carlos' listing of the rules:

Backslash is the escape character; always escape quotes; only escape backslashes if they precede a quote.

Published Thursday, October 05, 2006 1:00 AM by Jon Galloway
Filed under: ,

Comments

# re: [.NET Gotcha] Commandline args ending in \" are subject to CommandLineToArgvW whackiness

There's a mistake in your post.  The version with five tailing backslashes "\\this is a test\\\\\" yields:

\\this is a test\\"

Note the trailing quote.  The MSDN docs are slightly wrong.  They should read:

* 2n backslashes followed by a quotation mark produce n backslashes followed by an *unescaped* quotation mark.

* (2n) + 1 backslashes followed by a quotation mark again produce n backslashes followed by an *escaped* quotation mark.

An unescaped quotation mark followed by a space terminates the current parameter.  Unescaped quotation marks never appear in your argument list.  E.g. the parameter "a"b" yields:

ab

And finally (just to confuse things further) you can also escape quotes by doubling them up.

Thursday, October 05, 2006 12:12 PM by Carlos

# re: [.NET Gotcha] Commandline args ending in \" are subject to CommandLineToArgvW whackiness

Thanks for that.  It's definitely confusing when .NET doesn't do the "reasonable" thing...

Tuesday, February 10, 2009 3:38 PM by bdukes