Код выхода PowerShell - вызов из MSBuild - PullRequest
12 голосов
/ 28 апреля 2011

Я вызываю скрипт PowerShell из MSBuild. MSBuild может захватить возвращенный результат, но думает, что проект построен успешно.

Проблема в том, что код выхода из PowerShell не передается команде в MSBuild. Кто-то пробовал это раньше и смог бросить код выхода в MSBuild?

testmsbuild.proj

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="DesktopBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <ScriptLocation>c:\scripts\test.ps1</ScriptLocation>
  </PropertyGroup>

  <Target Name="AfterDropBuild" >
        <Exec Command="powershell.exe -NoProfile -Noninteractive -command &quot;&amp; { $(ScriptLocation)%3Bexit $LASTEXITCODE }&quot; " >
        <Output TaskParameter="ExitCode" PropertyName="ErrorCode"/>
        </Exec>
   </Target>    

 </Project>

test.ps1 (конечно, это приведет к ошибке)

function CallFromMSBuild {

   Invoke-command {Powershell.exe C:\a.ps1} -computername $computers
} 

Когда запускается проект MSBuild, он должен был обнаружить проблему, и сборка должна была завершиться неудачно (вместо этого сборка считается успешной)

Когда я звоню из MSBuild

C:\Scripts>msbuild testmsbuild.proj /t:AfterDropBuild
Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.225]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

Build started 4/28/2011 2:46:29 PM.
Project "C:\scripts\testmsbuild.proj" on node 1 (AfterDropBuild target(s)).
AfterDropBuild:
  powershell.exe -NoProfile -Noninteractive -command "& { c:\scripts\test.ps1;e
  xit $LASTEXITCODE }"
  Invoke-Command : Cannot validate argument on parameter 'ComputerName'. The argu
  ment is null or empty. Supply an argument that is not null or empty and then tr
  y the command again.
  At C:\install\test.ps1:3 char:58
  +    Invoke-command {Powershell.exe C:\a.ps1} -computername <<<<  $computers
      + CategoryInfo          : InvalidData: (:) [Invoke-Command], ParameterBind
     ingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Power
     Shell.Commands.InvokeCommandCommand

Done Building Project "C:\scripts\testmsbuild.proj" (AfterDropBuild target(s)).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.04

Ответы [ 3 ]

15 голосов
/ 02 мая 2011

Этот вопрос является лучшим ответом в основной поисковой системе. лучший ответ - это от Джеймса Ковача (из Psake Fame - то есть он вроде FizzBinned по интеграции PowerShell и MSBuild).

В итоге, в файле ps1

  1. вставляет в его function exec {... (или использует сам psake)
  2. обертывание вызовов внешних EXE-файлов в exec { x.exe }
  3. не нужно делатьлюбой явный exit ... материал

Обработка ошибок по умолчанию распространяет исключение вверх как ERRORLEVEL из 1 из powershell.exe myscript.ps1, то есть в MSBuild <Exec, который вам не нужно делатьлюбая хитрость, призывающая игнорировать коды выхода и т. д. (если только вы не хотите сделать что-то условное для конкретного кода выхода, в котором вы хотите сделать IgnoreExitCode="true" и захватить его с помощью элемента <Output)

И последнее, что нужно понять, это то, что в PowerShell есть $? which - это результат последнего выражения (которое не имеет значения, если вы находитесь в режиме ErrorAction='Stop'), которое меняется с каждым, что вы делаете, тогда как $ LastExitCode - это код выхода 'DOS' последнего .exe, запущенного в системе., Подробности здесь - обязательно прочитайте комментарии

4 голосов
/ 29 апреля 2011

Добавить exit $lastexitcode к test.ps1

После комментария:

Попробуйте это в test.ps1:

trap {Write-Host -foreground red $_.Exception.Message; exit 1; continue} Invoke-command   {Powershell.exe C:\a.ps1} -computername $computers

В принципе, я не думаю, что MSBuild виноват здесь.

Я ошибся Invoke-Command, и $lastexitcode был установлен в 0, хотя команда Invoke-Command завершилась неудачно! Вы можете проверить, работает ли это или нет из самого cmd, выполнив echo %errorlevel% и посмотреть, что вы получаете 1.

0 голосов
/ 06 ноября 2018

Я пробовал несколько вариантов, но ни один не работает для меня.

Чтобы зафиксировать ошибку powershell в цели msbuild, лучше всего вернуть код ошибки из сценария powershell, например $ host.SetShouldExit ($ remotelastexitcode).

например, test1.ps1

function CallFromMSBuild {

   Invoke-command {Powershell.exe C:\a.ps1} -computername $computers
   $host.SetShouldExit(1)
} 

<Target Name="AfterDropBuild" >
        <Exec Command="powershell.exe -NoProfile -Noninteractive -command &quot;&amp; { $(ScriptLocation)%3Bexit $LASTEXITCODE }&quot; " >
        <Output TaskParameter="ExitCode" PropertyName="ErrorCode"/>
        </Exec>
   </Target>   

Стоит взглянуть на https://snagify.wordpress.com/2008/04/06/teambuild-powershell-and-exit-codes/

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