Как подавить кавычки в командах PowerShell для исполняемых файлов - PullRequest
4 голосов
/ 12 апреля 2010

Есть ли способ подавить кавычки вокруг каждого аргумента командной строки, которые PowerShell любит генерировать, а затем передавать внешним исполняемым файлам для аргументов командной строки, в которых есть пробелы?

Вот ситуация:

Один из способов распаковать множество инсталляторов - это команда вида:

msiexec /a <packagename> /qn TARGETDIR="<path to folder with spaces>"

Попытка выполнить это из PowerShell оказалась довольно сложной. PowerShell любит заключать параметры с пробелами в двойные кавычки. Следующие строки:

msiexec /a somepackage.msi /qn 'TARGETDIR="c:\some path"'

msiexec /a somepackage.msi /qn $('TARGETDIR="c:\some path"')

$td = '"c:\some path"'

msiexec /a somepackage.msi /qn TARGETDIR=$td

Все результаты в следующей командной строке (как сообщается Win32 GetCommandLine () API):

"msiexec" /a somepackage.msi /qn "TARGETDIR="c:\some path""

Эта командная строка:

msiexec /a somepackage.msi TARGETDIR="c:\some path" /qn

результат в

"msiexec" /a fooinstaller.msi "TARGETDIR=c:\some path" /qn

Кажется, что PowerShell любит заключать результаты выражений, предназначенных для представления одного аргумента в кавычках, при передаче их во внешние исполняемые файлы. Это прекрасно работает для большинства исполняемых файлов. Тем не менее, MsiExec очень специфичен в отношении правил цитирования, которые он хочет, и не будет принимать ни одну из командных строк, генерируемых PowerShell для путей, в которых есть пробелы.

Есть ли способ подавить это поведение?

Ответы [ 6 ]

8 голосов
/ 13 апреля 2010

Избегайте внутренних кавычек, как это:

msiexec /a somepackage.msi TARGETDIR=`"c:\some path`" /qn
7 голосов
/ 22 октября 2010

Вот функция, которую я использую для лучшей обработки нескольких аргументов и аргументов с пробелами и кавычками. Обратите внимание, что нижеприведенные блоки кода не окрашивают там, где строки начинаются и заканчиваются правильно, и вы должны использовать `для экранирования кавычек, которые вы хотите в параметре.

function InstallMSIClient{
$Arguments = @()
$Arguments += "/i"
$Arguments += "`"$InstallerFolder\$InstallerVerFolder\Install.msi`""
$Arguments += "RebootYesNo=`"No`""
$Arguments += "REBOOT=`"Suppress`""
$Arguments += "ALLUSERS=`"1`""
$Arguments += "/passive"

Write-Host "Installing $InstallerVerFolder."
Start-Process "msiexec.exe" -ArgumentList $Arguments -Wait }

В моем блоге есть более полный пример. [http://www.christowles.com]

0 голосов
/ 17 ноября 2011

Я только что столкнулся с проблемой. У меня сработало следующее:

&cmd /c "msiexec /i `"$appName.msi`" /l* `"$appName.msi.log`" /quiet TARGETDIR=`"D:\Program Files (x86)\$appName\`""

Ключ выполнял cmd, а не msiexec напрямую. Это имело два преимущества:

  1. Я мог бы обернуть всю команду msiexec в строку, чтобы она разрешала переменную $ appName, все еще используя обратную черту, чтобы экранировать кавычки вокруг TARGETDIR.
  2. Мне удалось использовать $ LastExitCode для проверки успеха / неудачи операции msiexec. По какой-то причине $ LastExitCode не устанавливается при непосредственном вызове msiexec (hat-tip: http://www.powergui.org/thread.jspa?threadID=13022)
0 голосов
/ 23 июля 2010

У меня нет ответа, но этот парень, похоже, что-то задумал. http://www.eggheadcafe.com/software/aspnet/33777311/problem-escaping-command.aspx

Да, похоже, в конце они нашли решение:

Наконец-то выяснили, как это сделать, используя выражение-выражение:

$installprop = "TARGETDIR=" + "```"" + $installpath + "```""

invoke-expression "msiexec /i $packagepath $installprop"

Я бы порекомендовал использовать здесь-строку, чтобы избежать необходимости выполнять все экранирование.

$command = @'
msiexec /a <packagename> /qn TARGETDIR="<path to folder with spaces>"
'@

invoke-expression $command
0 голосов
/ 19 мая 2010

У меня нет ответа, но этот парень, похоже, на что-то.
http://www.eggheadcafe.com/software/aspnet/33777311/problem-escaping-command.aspx

Я не мог заставить это работать на меня.

Вот еще кто-то, кто тоже сообщает о проблеме: _ http://powershell.com/cs/forums/p/2809/3751.aspx

Вот еще одна идея от кого-то: _ http://www.roelvanlisdonk.nl/?p=1135

Это тоже не сработало для меня ...

0 голосов
/ 13 апреля 2010

Поместите весь аргумент в кавычки и избегайте внутренних кавычек. В противном случае PowerShell попытается разобрать его:

msiexec /a <packagename> /qn 'TARGETDIR=\"<path to folder with spaces>\"'
...