在 msi 的命令行上设置公共属性值遵循模式
MyInstaller.msi PUBLICPROPERTY="someValue"
这适用于“命令提示符”,即 cmd.exe 和 powershell。
但是
MyInstaller.msi PUBLICPROPERTY=""
在 powershell 中无法按预期工作。我预计它将 PUBLICPROPERTY 设置为 null,但它将 PUBLICPROPERTY 设置为值“CURRENTDIRECTORY =”C:emp \ msi \“”(它确实像 cmd.exe 预期的那样工作)。
为什么 powershell 和 cmd.exe 的行为不同,如何修复?
Windows 上的 PowerShell 必然会在幕后对您的论点执行重新引用。
这种不可见的重新引用并不总是按预期工作,例如在本例中。
更新:
--%
- 默认不再工作 ,并要求您(临时)设置 $PSNativeCommandArgumentPassing
首先= 'Legacy'
- 请参阅此答案了解详细信息。您可以通过调整您的引用来解决问题:
... PUBLICPROPERTY=`"`" # `-escape the " chars.
... 'PUBLICPROPERTY=""' # use enclosing '...', so " chars. can be used as-is
请注意,如果您想在参数中包含 PowerShell 变量/表达式的值,则使用
'...'
将不起作用。
--%
(停止解析符号)来使 PowerShell 按原样传递剩余参数,就好像您从 cmd.exe
/ 批处理文件调用 (包括环境变量引用的扩展,例如 %OS%
)。
... --% PUBLICPROPERTY=""
同样,您将无法以这种方式在参数中引用 PowerShell 变量或表达式。
至于如果没有上述技术会发生什么:
PUBLICPROPERTY="someValue"
变成
PUBLICPROPERTY=someValue
PUBLICPROPERTY="some Value"
,由于空格,变成了
"PUBLICPROPERTY=some Value"
,即整个参数包含在
"..."
中。
内部诸如PUBLICPROPERTY="someValue"
之类的参数有其引号stripped:如果将此类参数传递给PowerShell cmdlet或函数,它只会看到
PUBLICPROPERTY=someValue
。将这样的值传递给
外部程序时,PowerShell会根据情况决定是否需要双引号,但该引用仅应用于整个参数 - "
字符的初始位置。丢失了。
PUBLICPROPERTY="someValue"
变成
PUBLICPROPERTY=someValue
并按原样传递,因为它不包含嵌入的空格,因此 PowerShell 不应用双引号。 相比之下,
PUBLICPROPERTY="some Value"
会变成PUBLICPROPERTY=some Value
,并作为
"PUBLICPROPERTY=some Value"
传递,因为空格的存在需要双引号,以便将值保留为单个参数。
请注意,PowerShell 仅对传递给外部程序的参数应用双引号
,因为这是唯一可以假定所有程序都能理解的引用样式。 重新引用逻辑随着时间的推移而发生了变化,并且存在 错误,遗憾的是,由于向后兼容性问题,这些错误将继续存在
。
例如,'3 " of rain'
变成了
"3 " of rain"
,即
破碎,因为
嵌入的
"
缺乏转义;解决方法是预见到这一点,并显式执行 PowerShell 应该执行的操作:自动:将嵌入的
"
转义为 \"
,以利于外部程序:'3 \" of rain'