在命令行上设置 Public 属性 值

Setting Public Property Values on the Command Line

Setting Public Property Values on the Command Line 的 msi 遵循模式

MyInstaller.msi PUBLICPROPERTY="someValue"

这适用于 "Command Prompt" 又名 cmd.exe 和 powershell。

但是

MyInstaller.msi PUBLICPROPERTY=""

在 powershell 中没有像预期的那样工作。我预计它将 PUBLICPROPERTY 设置为 null 但它将 PUBLICPROPERTY 设置为值 "CURRENTDIRECTORY="C:\temp\msi\"" (它确实像 cmd.exe 预期的那样工作)。

为什么 powershell 和 cmd.exe 行为不同,如何解决?

PowerShell 在 Windows 必要时,在幕后执行 重新引用 您的论点。

这种不可见的重新引用并不总是按预期工作,例如在这种情况下。

您可以通过调整您的引用来解决问题:

... PUBLICPROPERTY=`"`"  # `-escape the " chars.

... 'PUBLICPROPERTY=""'  # use enclosing '...', so " chars. can be used as-is

请注意,如果您想在参数中包含 PowerShell 变量/表达式的值,则使用 '...' 将不起作用。

此外,在 PSv3+ 中,您可以使用 --%, the stop-parsing symbol,使 PowerShell 按原样传递其余参数,就像您从 cmd.exe / 批处理文件中调用一样(包括扩展环境变量引用,例如%OS%)。

... --% PUBLICPROPERTY=""

同样,您将无法以这种方式在参数中引用 PowerShell 变量或表达式。


至于没有上述技巧会发生什么:

  • PUBLICPROPERTY="someValue"变为
    PUBLICPROPERTY=someValue

  • PUBLICPROPERTY="some Value",由于空格,变成
    "PUBLICPROPERTY=some Value",即 整个参数 包含在 "...".

PowerShell-内部 一个参数如 PUBLICPROPERTY="someValue" 有它的引号 stripped:如果你将这样的参数传递给PowerShell cmdlet 或函数,它只会看到 PUBLICPROPERTY=someValue.

将这样的值传递给外部程序时,PowerShell 根据情况决定是否需要双引号,但该引号是然后只应用于 整个参数 - " 字符的初始位置。丢了。

因此,PUBLICPROPERTY="someValue" 变成 PUBLICPROPERTY=someValue 并按原样 传递 ,因为它 不包含嵌入的空格 ,因此 PowerShell 不应用双引号。

相比之下,PUBLICPROPERTY="some Value" 变成 PUBLICPROPERTY=some Value,它作为 "PUBLICPROPERTY=some Value" 传递,因为空格的存在需要双引号才能将值保留为单个值争论。

请注意,PowerShell 只对传递给外部程序的参数应用-引用,因为这是唯一的引用方式可以假定所有程序都可以理解。

重新引用的逻辑随着时间的推移发生了变化,并且 bugs, which, regrettably, are here to stay 由于向后兼容性问题。

例如,'3 " of rain' 变为 "3 " of rain",这是 损坏的 ,因为 嵌入的 " 缺少转义 ;解决方法是预测并明确执行 PowerShell 应该自动执行的操作 :为了外部程序的利益,将嵌入式 " 转义为 \"'3 \" of rain'