Каноническое решение для экранирования аргументов командной строки .NET

Вопрос. Учитывая имя файла и произвольный список строк, существует ли канонический способ создания единой командной строки, так что Environment.GetCommandLineArgs (и С# void main(String[] args)/VB Sub Main(args() As String)) вернет тот же список строк?


Фон: способ, которым .NET разбивает командную строку на аргументы, удивительно сложный, например:

Если знак двойной кавычки следует за двумя или четным числом обратных косых черт, каждая последующая обратная косая черта заменяется одной обратной косой чертой, а знак двойной кавычки удаляется. Если знак двойной кавычки следует за нечетным числом обратных косых черт, включая только одну, каждая предыдущая пара заменяется одной обратной косой чертой, а оставшаяся обратная косая черта удаляется; однако в этом случае знак двойной кавычки не удаляется.

Многие пробовали простой "поместить каждый аргумент в двойные кавычки и избежать существующих двойных кавычек" и сбой, как только один из аргументов содержит обратную косую черту. В этой статье возникли различные вопросы по StackOverflow, например:

Тем не менее, их ответы либо не являются достаточно общими, чтобы обеспечить каноническое решение для всех случаев или, как представляется, развиваться "итеративно" ( "О, там еще один частный случай, который я забыл, добавьте его, и теперь он должен охватывать большинство случаев..." ). Поскольку это довольно распространенная проблема, я бы хотел увидеть решение, обеспечивающее доверие, например, с помощью
  • исходя из авторитетного источника (возможно, запись в блоге от одного из разработчиков, участвующих в этом сумасшедшем соглашении с командной строкой) или
  • обеспечивает формальное доказательство того, что данный алгоритм удовлетворяет требованиям командной строки .NET.

Ответы

Ответ 1

Этот алгоритм является общим и исходит из относительно авторитетного источника (блоги MSDN).

Ответ 2

Несколько лет назад Microsoft объявила, что собирается выпустить синтаксический анализатор командной строки на CodePlex (вместо System.Shell.CommandLine, который должен был поставляться с .NET Framework 4). Я не уверен, действительно ли они это сделали. Если вы хотите, чтобы синтаксический анализатор, разработанный сотрудником Microsoft, просмотрел cmdline. Также вы можете искать анализы командной строки в CodePlex.

Вы также можете попробовать Mono.Options, который достаточно мощный.