Как вызвать MSBuild из PowerShell с помощью оператора &? - PullRequest
31 голосов
/ 15 мая 2009

Я только что проверил это на PowerShell v1.0. Настройка выглядит следующим образом:

 Id CommandLine
 -- -----------
  1 $msbuild = "C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe"
  4 $a = "C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build"

.

Эта строка завершается с неинтуитивным сообщением об ошибке:

 Id CommandLine
 -- -----------
  5 & $msbuild $a

.

Эта строка не выполнена, поскольку & ожидает, что первым аргументом будет сама команда. Id CommandLine -- ----------- 10 & "$msbuild $a" .

Эта строка работает:

 Id CommandLine
 -- -----------
 16 cmd /c "$msbuild $a"

.

Пожалуйста, объясните. Меня больше интересует, почему синтаксис & не работает, чем обходной путь для MSBuild.

Ответы [ 3 ]

35 голосов
/ 15 мая 2009

Тьфу.

$collectionOfArgs = @("C:\some\project\or\other\src\Solution.sln", 
    "/target:Clean", "/target:Build")
& $msbuild $collectionOfArgs

Это работает. & принимает набор аргументов, поэтому вы должны разделить строки, содержащие несколько аргументов, на набор строковых аргументов.

31 голосов
/ 16 мая 2009

Проблемы, с которыми вы сталкиваетесь в результате анализа аргументов PowerShell. В первом примере, когда PowerShell видит $ a, он передает его как единственный параметр msbuild. Это можно увидеть с помощью утилиты echoargs из PSCX :.

PS> $a = "C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build"
PS> & echoargs $a
Arg 0 is <C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build>

Второй пример еще хуже, потому что вы говорите powershell, чтобы он вызывал «$ echoargs $ a» в качестве имени команды, а это неверное имя команды.

Третья строка работает, потому что CMD.exe получает расширенную форму «$ echoargs $ a» в качестве единственного аргумента, который анализирует и выполняет:

У вас есть несколько вариантов здесь. Сначала я делаю это так:

PS> & $msbuild C:\some\project\or\other\src\Solution.sln `
    /target:Clean /target:Build

Другой вариант - использовать выражение Invoke-Expression следующим образом:

PS> Invoke-Expression "$msbuild $a"

В целом, я стараюсь быть очень осторожным с Invoke-Expression, особенно если какая-либо часть вызываемой строки предоставляется пользователем.

3 голосов
/ 13 марта 2016

Вы также можете попробовать использовать бесплатный Invoke-MsBuild powershell скрипт / модуль . По сути, это дает вам командлет Invoke-MsBuild PowerShell, который вы можете вызывать вместо попытки вручную запустить msbuild.exe.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...