Дубликат вопроса и ответа, который я опубликовал , здесь для потомков, когда голосование было закрыто. Ключевое отличие состоит в том, что этот вопрос был ограничен до OOTB , и мой ответ на вопрос остается в рамках этого ограничения.
Вопрос
Похоже, у Powershell нет простого способа вызвать его с помощью произвольной команды, а затем вызвать ошибки синтаксического анализа и выполнения таким образом, чтобы правильно взаимодействовать с вызывающими, не являющимися PowerShell, - например, cmd.exe
, TeamCity и т. Д.
Мой вопрос прост. Как мне лучше всего использовать OOTB MSBuild v4 и PowerShell v3 (открыт для предложений - не исключаю подходящую для производства задачу MSBuild, но она должна быть немного сильнее, чем предполагать: «это просто» - взяв пример PowerShell Task Factory и настроить его и / или стать его сопровождающим / родительским ") для запуска команды (либо небольшого сегмента скрипта, либо (чаще всего) вызова скрипта .ps1
.
Я думаю, это должно быть что-то нормальное, вроде:
<Exec
IgnoreStandardErrorWarningFormat="true"
Command="PowerShell "$(ThingToDo)"" />
К сожалению, это не работает: -
- если
ThingToDo
не удается разобрать, он молча завершается
- если
ThingToDo
- это вызов сценария, который не существует, он завершается ошибкой
- Если вы хотите распространить
ERRORLEVEL
основанный .cmd
результат, он становится волосатым
- , если вы хотите вставить
"
кавычки в ThingToDo
, он не будет работать
Итак, каким должен быть пуленепробиваемый способ запуска PowerShell из MSBuild? Могу ли я что-нибудь сделать PsGet , чтобы все было в порядке?
Ответ
Ну-а-а-а, вы можете использовать что-то длинное, как это, пока не найдете лучший способ: -
<PropertyGroup>
<__PsInvokeCommand>powershell "Invoke-Command</__PsInvokeCommand>
<__BlockBegin>-ScriptBlock { $errorActionPreference='Stop';</__BlockBegin>
<__BlockEnd>; exit $LASTEXITCODE }</__BlockEnd>
<_PsCmdStart>$(__PsInvokeCommand) $(__BlockBegin)</_PsCmdStart>
<_PsCmdEnd>$(__BlockEnd)"</_PsCmdEnd>
</PropertyGroup>
И тогда «все», что вам нужно сделать, это:
<Exec
IgnoreStandardErrorWarningFormat="true"
Command="$(_PsCmdStart)$(ThingToDo)$(_PsCmdEnd)" />
Единственная особенность этой возможности (кроме перехвата всех типов ошибок, о которых я мог думать), заключается в том, что она работает OOTB с любой версией PowerShell и любой версией MSBuild.
Я возьму свое пальто.