Установка значений общедоступных свойств в командной строке

общедоступный Значения свойств в командной строке msi следуют шаблону

MyInstaller.msi PUBLICPROPERTY="someValue"

Это работает в «командной строке», также известной как cmd.exe и powershell.

Но

MyInstaller.msi PUBLICPROPERTY=""

работает не так, как ожидалось в PowerShell. Я ожидал, что он устанавливает для PUBLICPROPERTY значение null, но устанавливает для PUBLICPROPERTY значение "CURRENTDIRECTORY =" C: \ temp \ msi \ "" (это работает, как и ожидалось, с cmd.exe).

Почему поведение powershell и cmd.exe отличается и как это исправить?


person stefan.seeland    schedule 09.08.2018    source источник
comment
Я собирался добавить комментарий, но теперь уже вижу ответ. Позвольте мне просто добавить, что в дополнение к попытке PUBLICPROPERTY=`"`", я думаю, вы можете назначить: PUBLICPROPERTY="{}", чтобы ничего не установить для свойства. Просто стрельба от бедра, не проверял.   -  person Stein Åsmul    schedule 09.08.2018
comment
Это тоже была первая догадка, и: no: это не работает. Скобки записываются как значение.   -  person stefan.seeland    schedule 09.08.2018


Ответы (1)


PowerShell в Windows при необходимости выполняет повторное цитирование ваших аргументов за кулисами.

Это невидимое повторное цитирование не всегда работает должным образом, например, в этом случае.

Вы можете решить эту проблему, изменив цитату:

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

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

Обратите внимание, что использование '...' не будет работать, если вы хотите включить в аргумент значения переменных / выражений PowerShell.

Кроме того, в PSv3 + вы можете использовать --%, символ остановки анализа, чтобы PowerShell передавал оставшиеся аргументы как есть, как если бы вы вызывались из cmd.exe / пакетного файла (включая расширение ссылки на переменные среды, например %OS%).

... --% PUBLICPROPERTY=""

Опять же, вы не сможете ссылаться на переменные или выражения PowerShell в аргументах таким образом.


Что касается того, что происходит без описанных выше методов:

  • PUBLICPROPERTY="someValue" становится
    PUBLICPROPERTY=someValue

  • PUBLICPROPERTY="some Value" из-за пробела становится
    "PUBLICPROPERTY=some Value", т. Е. весь аргумент заключен в "...".

PowerShell - внутренне аргумент, такой как PUBLICPROPERTY="someValue", имеет свои кавычки удалены: если вы передадите такой аргумент командлету или функции PowerShell, он увидит только 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'

person mklement0    schedule 09.08.2018