转义 .NET 命令行参数的规范解决方案

Posted

技术标签:

【中文标题】转义 .NET 命令行参数的规范解决方案【英文标题】:Canonical solution for escaping .NET command line arguments 【发布时间】:2012-11-27 14:48:10 【问题描述】:

问题:给定一个文件名和一个任意字符串列表,是否有一种规范的方式来创建单个命令行,例如 Environment.GetCommandLineArgs(和 C# 的 @ 987654327@/VB 的Sub Main(args() As String)) 会返回相同的字符串列表吗?


背景:.NET 将命令行拆分为参数的方式是surprisingly complex,例如:

如果双引号跟在两个或偶数个反斜杠之后,则将前面的每个反斜杠对替换为一个反斜杠并删除双引号。如果双引号后跟奇数个反斜杠,包括一个,则前面的每一对都被一个反斜杠替换,其余的反斜杠被删除;但是,在这种情况下,双引号不会被删除。

许多人尝试简单的“将每个参数放在双引号中并转义现有的双引号”方法,但一旦其中一个参数包含尾部反斜杠,就会失败。 *** 上有关于这个问题的各种问题,例如:

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

但是,他们的答案要么不够笼统,无法为所有案例提供规范的解决方案,要么似乎是“迭代地”开发的(“哦,我忘记了另外一个特殊情况,让我们添加它并现在 em> 它应该涵盖大多数情况...")。由于这是一个相当普遍的问题,我希望看到一个提供信心的解决方案,例如,通过任一

来自权威来源(可能是参与此疯狂命令行约定的开发人员之一的博客条目)或 提供给定算法满足 .NET 命令行要求的正式证明。

【问题讨论】:

追求一个通用的解决方案来解决这个问题是非常低效的。将数据写入文件,改为传递文件的路径。 我同意汉斯的观点。获得解决方案后,您会如何处理? @HansPassant:您并不总是能够控制被调用的应用程序(今天许多应用程序确实使用多个命令行参数)。因此,calling 应用程序的编写者可能希望确保参数被正确编码(理想情况下,不必每次都重新发明***并详细研究 Windows/.NET 命令行转义语法) . 【参考方案1】:

This algorithm 是通用的,来自相对权威的来源(MSDN 博客)。

【讨论】:

谢谢,这看起来很有用。但是,它提出了CommandLineToArgvW 和Environment.GetCommandLineArgs 行为是否相同的问题。一些消息来源声称确实如此,但在“偶数个反斜杠加引号”的情况下,文档似乎有所不同。 看看documentation for older versions of .NET。不同的版本记录了不同的行为。这是一团糟:)【参考方案2】:

几年前,微软宣布他们将在 CodePlex 上发布命令行解析器(而不是应该与 .NET Framework 4 一起发布的 System.Shell.CommandLine)。我不确定他们是否真的这样做了。如果您想要由 Microsoft 员工开发的解析器,请查看 cmdline。您也可以在CodePlex 中查找命令行解析。

你也可以试试Mono.Options,它很强大。

【讨论】:

问题是关于创建一个命令行,而不是解析一个-1。

以上是关于转义 .NET 命令行参数的规范解决方案的主要内容,如果未能解决你的问题,请参考以下文章

如何转义任意字符串以用作 Bash 中的命令行参数?

如何阻止我的命令行参数在 Maven 插件中被转义?

在 Windows 脚本中读取命令行参数时,有没有办法转义逗号字符?

如何转义变量中的特殊字符以在 bash 中提供命令行参数

Shell命令行中特殊字符与其转义详解(去除特殊含义)

文件路径作为命令行参数