PowerShell退出代码 - 从MSBuild调用
我正在从MSBuild调用PowerShell脚本。 MSBuild能够捕获返回的输出,但认为该项目已成功构建。PowerShell退出代码 - 从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 "& { $(ScriptLocation)%3Bexit $LASTEXITCODE }" " >
<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
添加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失败!你可以通过做echo %errorlevel%
并看到你得到1来测试它是否有效。从这个cmd本身可以测试。
不幸运!还是一样。从PowerShell窗口直接运行退出代码是255 – Sanjeev 2011-04-28 20:35:52
我已经编辑了我的回复 – manojlds 2011-04-28 20:46:37
感谢您的更新。陷阱{}是诀窍!现在MSbuild说“构建失败”。问题在于它没有显示$ ._ Exception.Message思想。它显示的是'代码'C:\ scripts \ testmsbuild.proj(12,3):错误MSB3073:使用代码1'代码'退出命令“powershell.exe c:\ scripts \ test.ps1”。一半的战斗结束了,虽然:) – Sanjeev 2011-04-28 21:07:18
这个问题是一个主要搜索引擎的最佳答案。来自James Kovacs的best answer is this(psake的名声 - 即他在PowerShell和MSBuild集成上有点类似FizzBinned)。
综上所述,在PS1文件:
- 在你的脚本的顶部贴
$ErrorActionPreference='Stop'
所以它不是默认的,这是SilentlyContinue
(在接受答案的trap
位有同样的效果,但更为间接和混乱) - 棍子在他
function exec {...
(或使用psake本身)外部的EXE的一个exec { x.exe }
- 包装调用不需要做任何expli CIT
exit ...
东西
默认的错误处理传播异常起来为1的ERRORLEVEL
从powershell.exe myscript.ps1
,即在一个MSBuild <Exec
你不需要做任何弄虚作假再告诉它忽略退出代码等。(除非你想做些什么具体的退出代码的条件,要在其中做IgnoreExitCode="true"
并与<Output
元素捕捉到它)
了解的最后一个重要的事情是,在PowerShell中,有一个$?
这是最后一个表达式的结果(与ErrorAction='Stop'
模式无关)随着每个事情而变化,而$ LastExitCode是系统中触发的最后一个.exe的'DOS'退出代码。 Details here - be sure to read the comments
甜!感谢您的信息。我使用博客链接中提到的“Exec function”代码来捕获来自另一个PS脚本(remoteinvoke.ps1)的错误,该脚本从myscript.ps1中调用远程计算机。陷阱在这些情况下不起作用。我会写一篇关于我的发现的详细文章(并在此链接),以及exec如何帮助我解决问题:D – Sanjeev 2011-05-02 16:40:33
@Sanjeev:很高兴听到它。当然,在大多数情况下,一个“陷阱”(错误goto':P)比'错误恢复下一个'要好得多。但它肯定会很好,得到实际相关的位的另一个总结,而不是堆积在许多小事情,以迫使它工作... – 2011-05-03 23:24:29
@RubenBartelink关于http://geekswithblogs.net/dwdii /archive/2011/05/27/part-2-automating-a-visual-studio-build-with-powershell.aspx? – Kiquenet 2013-05-03 07:16:47
相关:http://stackoverflow.com/questions/78069/any-good-powershell-msbuild-tasks – 2012-12-13 21:46:14