任何人都知道将执行 PowerShell 脚本并传递不同参数的任何好的 MSBuild 任务吗?
我能够找到B# .NET 博客:Invoking PowerShell scripts from MSBuild,但我希望得到一些更精致的东西。
如果我找不到任何东西,我当然会继续使用该博客文章作为入门来完善我自己的内容。
任何人都知道将执行 PowerShell 脚本并传递不同参数的任何好的 MSBuild 任务吗?
我能够找到B# .NET 博客:Invoking PowerShell scripts from MSBuild,但我希望得到一些更精致的东西。
如果我找不到任何东西,我当然会继续使用该博客文章作为入门来完善我自己的内容。
对于 3.5,可以使用http://powershellmsbuild.codeplex.com/ 。如果有一个可以通过 NuGet package restore 使用的 NuGet 包,那就太好了。
4.0 有一个Windows Powershell 任务工厂,您可以在代码库中获得它已被纳入
MSBuild 扩展包(顶级任务库之一 - 400 多个任务并在 MSBuild 内部推荐)有(从下载部分PowerShellTaskFactory
下载帮助文件这个示例发布有一个偷看)。
您可能还想查看Psake - 基于 PowerShell 的构建环境。
我发布了重复的问题和答案,在这里为后代投票关闭。关键区别在于,这个问题被限制为OOTB,而我的自我回答保持在该限制范围内。
Powershell 似乎没有一种简单的方法来使用任意命令触发它,然后以与非 PowerShell 的调用者正确互操作的方式冒泡解析和执行错误 - 例如cmd.exe
,TeamCity等。
我的问题很简单。使用 OOTB MSBuild v4 和 PowerShell v3 对我来说最好的方法是什么(接受建议 - 不会排除适合生产的 MSBuild 任务,但它需要比建议“这很容易 - 使用 PowerShell 任务工厂示例和调整它和/或成为它的维护者/父”)来运行一个命令(一个小的脚本段,或者(最常见的)一个.ps1
脚本的调用。
我认为它应该是正常的,例如:
<Exec
IgnoreStandardErrorWarningFormat="true"
Command="PowerShell "$(ThingToDo)"" />
可悲的是,这不起作用:-
ThingToDo
解析失败,则静默失败ThingToDo
是不存在的脚本调用,则失败ERRORLEVEL
基于.cmd
结果的结果,它会变得毛茸茸的"
引号ThingToDo
,它将不起作用那么,从 MSBuild 运行 PowerShell 的防弹方法应该是什么?有什么我可以PsGet让一切正常的吗?
Weeeeelll,您可以使用像这样冗长的东西,直到找到更好的方法:-
<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)" />
这个唯一的赎回功能(除了捕获我能想到的所有错误类型)是它适用于任何 PowerShell 版本和任何 MSBuild 版本的 OOTB。
我去拿我的外套。
带着一点乐趣,我设法想出了一个相当干净的方法来完成这项工作:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- #1 Place this line at the top of any msbuild script (ie, csproj, etc) -->
<PropertyGroup><PowerShell># 2>nul || type %~df0|find /v "setlocal"|find /v "errorlevel"|powershell.exe -noninteractive -& exit %errorlevel% || #</PowerShell></PropertyGroup>
<!-- #2 in any target you want to run a script -->
<Target Name="default" >
<PropertyGroup> <!-- #3 prefix your powershell script with the $(PowerShell) variable, then code as normal! -->
<myscript>$(PowerShell)
#
# powershell script can do whatever you need.
#
dir ".\*.cs" -recurse |% {
write-host Examining file named: $_.FullName
# do other stuff here...
}
$answer = 2+5
write-host Answer is $answer !
</myscript>
</PropertyGroup>
<!-- #4 and execute the script like this -->
<Exec Command="$(myscript)" EchoOff="true" />
</Target>
</Project>
如果您的 powershell 脚本需要使用 < > 或 & 字符,只需将内容放在 CDATA 包装器中:
<script2><![CDATA[ $(PowerShell)
# your powershell code goes here!
write-host "<<Hi mom!>>"
]]></script2>
如果您想将项目返回到 msbuild 脚本,您可以获取它们:
<script3>$(PowerShell)
# your powershell code goes here!
(dir "*.cs" -recurse).FullName
</script3>
<Exec Command="$(script3)" EchoOff="true" ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="items" />
</Exec>
<Touch Files="$(items)" />
看!然后您可以将这些项目与另一个 msbuild 任务一起使用:D