每个可执行文件都有自己的规则集,用于将可执行文件名后面的字符串拆分为可执行文件进一步处理的参数值。
Windows 命令处理器cmd.exe 将双引号字符串之外的水平制表符、普通空格、逗号、分号、等号和 OEM 编码的不间断空格(十六进制值 FF 的字节)解释为参数分隔符,因为它可以在运行名称为 test.cmd 的批处理文件时看到,只在命令提示符窗口中使用命令行 @echo %0 $1 $2 $3 $4
test argument1,,,"argument 2";;;"argument 3 contains a comma ',' a semicolon ';' an equal sign '=' and multiple spaces"===argument4
导致输出
test argument1 "argument 2" "argument 3 contains a comma ',' a semicolon ';' an equal sign '=' and multiple spaces" argument4
,,, 和 ;;; 和 === 被解释为参数字符串分隔符。
global assembly cache toolgacutil.exe 将传递给它的字符串拆分为与cmd.exe 不同的参数字符串。逗号和等号不被解释为参数分隔符。只有正常的空格字符被解释为参数分隔符,除了正常的空格在双引号参数字符串内。
对于 Windows 可执行文件,参数字符串之间的参数分隔符的数量无关紧要是很常见的。因此,如果两个参数字符串之间只使用一个空格或多个空格,则无关紧要。
在批处理文件中使用以下行会发生什么?
gacutil /u ^
Microsoft.IdentityModel.Clients.ActiveDirectory,^
Version=2.28.0.725,^
Culture=neutral,^
PublicKeyToken=31bf3856ad364e35
请先阅读:How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Windows 命令处理器cmd.exe 逐行读取批处理文件,在读取一行时将回车+换行替换为换行。
cmd.exe 将行尾的插入符号 ^ 解释为换行符换行符的转义字符,从而将下一行与当前行连接起来,直到到达末尾批处理文件或找到未使用^ 转义的换行符。在批处理文件中的行连接过程中不会删除任何字符。
批处理文件中每行前导三个正常空格的上述行的结果是:
gacutil /u Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.28.0.725, Culture=neutral, PublicKeyToken=31bf3856ad364e35
命令行开头留给gacutil的三个前导空格被cmd.exe删除,但所有其他空格都保留,因为cmd.exe无法知道它们是否对程序/脚本接下来运行很重要或不。所以在/u 之后有四个空格,在批处理文件的不同行中指定的其他字符串之间有三个空格。
gacutil.exe 现在将命令行解释为以下参数列表:
/u
Microsoft.IdentityModel.Clients.ActiveDirectory,
Version=2.28.0.725,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35
结果是一条错误消息,因为在这种情况下,gacutil.exe 必须只使用两个参数运行:
- 选项
/u 指示全局程序集缓存工具从全局程序集缓存中卸载程序集
- 和程序集名称
Microsoft.IdentityModel.Clients.ActiveDirectory,Version=2.28.0.725,Culture=neutral,PublicKeyToken=31bf3856ad364e35。
因此,在批处理文件中使用的在程序集名称参数字符串的各个部分之间的缩进空格未被cmd.exe 删除,使gacutil.exe 的命令行无效。
因此,在这种情况下,不可能在多行上定义带有缩进空格的程序集名称参数字符串,因为cmd.exe 如何连接行并保留空格,以及gacutil.exe 如何拆分传递给的字符串从cmd.exe 到参数。
不同的可执行文件可以将字符串拆分为不同的参数值列表,因此在带有缩进空格的批处理文件中的多行上写入可执行文件的参数可能适用于此可执行文件。
但是对于这个用例,可以在批处理文件中使用以下语法:
gacutil /u ^
^"Microsoft.IdentityModel.Clients.ActiveDirectory,^
Version=2.28.0.725,^
Culture=neutral,^
PublicKeyToken=31bf3856ad364e35^"
只要将整个程序集名称参数字符串括在双引号中,全局程序集缓存工具就不会出现程序集名称中逗号后的一个或多个空格的问题。出于这个原因,在程序集名称字符串的开头有一个",在末尾还有一个"。但是对于 Windows 命令处理器,两个双引号必须用 ^ 转义,否则 cmd.exe 会将每行末尾的插入符号 ^ 解释为文字字符,而不是转义字符。
cmd.exe 必须将分布在多行上的命令行解释为没有双引号中的参数字符串的行,以便将每个 ^ 解释为转义字符,而程序集名称在运行时实际上用双引号括起来最后用命令行gacutil.exe:
gacutil /u "Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.28.0.725, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
是的,这很奇怪。