Escape command line arguments in c#
.net, c#, command-line-arguments
Solution
It's more complicated than that though!
I was having related problem (writing front-end .exe that will call the back-end with all parameters passed + some extra ones) and so i looked how people do that, ran into your question. Initially all seemed good doing it as you suggest `arg.Replace (@"\", @"\\").Replace(quote, @"\"+quote)`.
However when i call with arguments `c:\temp a\\b`, this gets passed as `c:\temp` and `a\\b`, which leads to the back-end being called with `"c:\\temp" "a\\\\b"` - which is incorrect, because there that will be two arguments `c:\\temp` and `a\\\\b` - not what we wanted! We have been overzealous in escapes (windows is not unix!).
And so i read in detail http://msdn.microsoft.com/en-us/library/system.environment.getcommandlineargs.aspx and it actually describes there how those cases are handled: backslashes are treated as escape only in front of double quote.
There is a twist to it in how multiple `\` are handled there, the explanation can leave one dizzy for a while. I'll try to re-phrase said unescape rule here: say we have a substring of N `\`, followed by `"`. When unescaping, we replace that substring with int(N/2) `\` and iff N was odd, we add `"` at the end.
The encoding for such decoding would go like that: for an argument, find each substring of 0-or-more `\` followed by `"` and replace it by twice-as-many `\`, followed by `\"`. Which we can do like so:
s = Regex.Replace(arg, @"(\\*)" + "\"", @"$1$1\" + "\"");
That's all...
PS. ... not. Wait, wait - there is more! :)
We did the encoding correctly but there is a twist because you are enclosing all parameters in double-quotes (in case there are spaces in some of them). There is a boundary issue - in case a parameter ends on `\`, adding `"` after it will break the meaning of closing quote. Example `c:\one\ two` parsed to `c:\one\` and `two` then will be re-assembled to `"c:\one\" "two"` that will me (mis)understood as one argument `c:\one" two` (I tried that, i am not making it up). So what we need in addition is to check if argument ends on `\` and if so, double the number of backslashes at the end, like so:
s = "\"" + Regex.Replace(s, @"(\\+)$", @"$1$1") + "\"";
Problem
Short version: Is it enough to wrap the argument in quotes and escape `\` and `"` ? Code version I want to pass the command line arguments `string[] args` to another process using ProcessInfo.Arguments. ``` ProcessStartInfo info = new ProcessStartInfo(); info.FileName = Application.ExecutablePath; info.UseShellExecute = true; info.Verb = "runas"; // Provides Run as Administrator info.Arguments = EscapeCommandLineArguments(args); Process.Start(info); ``` The problem is that I get the arguments as an array and must merge them into a single string. An arguments could be crafted to trick my program. ``` my.exe "C:\Documents and Settings\MyPath \" --kill-all-humans \" except fry" ``` According to this answer I have created the following function to escape a single argument, but I might have missed something. ``` private static string EscapeCommandLineArguments(string[] args) { string arguments = ""; foreach (string arg in args) { arguments += " \"" + arg.Replace ("\\", "\\\\").Replace("\"", "\\\"") + "\""; } return arguments; } ``` Is this good enough or is there any framework function for this?