visual-studio 任何好的 PowerShell MSBuild 任务?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/78069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Any good PowerShell MSBuild tasks?
提问by Eric Schoonover
Anyone know of any good MSBuild tasks that will execute a PowerShell script and pass it different parameters?
任何人都知道将执行 PowerShell 脚本并向其传递不同参数的任何好的 MSBuild 任务?
I was able to find B# .NET Blog: Invoking PowerShell scripts from MSBuild, but I'm hoping for something that is a little more polished.
我能够找到B# .NET 博客:从 MSBuild 调用 PowerShell 脚本,但我希望有一些更完善的东西。
If I can't find anything I will of course just go ahead and polish my own using that blog post as a starter.
如果我找不到任何东西,我当然会继续使用该博客文章作为入门来完善我自己的内容。
回答by Ruben Bartelink
One could use http://powershellmsbuild.codeplex.com/for 3.5. It'd be nice if there was a NuGet package for it that one could leverage via NuGet package restore.
对于 3.5,可以使用http://powershellmsbuild.codeplex.com/。如果有一个可以通过 NuGet 包恢复利用的 NuGet 包,那就太好了。
4.0 has a Windows Powershell Task Factorywhich you can get in the code galleryhas been rolled into
MSBuild Extension Pack (one of the top task libraries - 400+ Tasks & recommended in Inside MSBuild)has PowerShellTaskFactory(download the help file from the download section of this example releaseto have a peek).
4.0 有一个Windows Powershell 任务工厂,您可以在代码库中获得它已被纳入
MSBuild 扩展包(顶级任务库之一 - 400 多个任务并在 Inside MSBuild 中推荐)具有PowerShellTaskFactory(从下载部分下载帮助文件)此示例发布一瞥)。
回答by Steven Murawski
回答by Ruben Bartelink
Duplicate Question and Answer I Posted, here for posterity for when it has been vote to closed. The key difference is that this question was constrained to being OOTBand my self-answer stays within that constraint.
我发布了重复的问题和答案,在这里供后代投票结束时使用。关键的区别在于,这个问题被限制为OOTB,而我的自我回答保持在该限制范围内。
Question
题
Powershell doesn't seem to have an easy way to trigger it with an arbitrary command and then bubble up parse and execution errors in a way that correctly interoperates with callers that are not PowerShell - e.g., cmd.exe, TeamCityetc.
PowerShell的似乎并不有一个简单的方法与任意命令,然后泡了解析和执行错误触发它的方式,正确地与呼叫者互操作是不是PowerShell的-例如cmd.exe,TeamCity的等等。
My question is simple. What's the best way for me with OOTB MSBuild v4 and PowerShell v3 (open to suggestions-wouldnt rule out a suitably production ready MSBuild Task, but it would need to be a bit stronger than suggesting "it's easy - taking the PowerShell Task Factory sample and tweak it and/or becoming it's maintainer/parent") to run a command (either a small script segment, or (most commonly) an invocation of a .ps1script.
我的问题很简单。OOTB MSBuild v4 和 PowerShell v3 对我来说最好的方法是什么(接受建议 - 不会排除适合生产的 MSBuild 任务,但它需要比建议“这很容易 - 采用 PowerShell 任务工厂示例和调整它和/或成为它的维护者/父母”)来运行一个命令(一个小脚本段,或者(最常见)一个.ps1脚本调用。
I'm thinking it should be something normal like:
我认为它应该是正常的,例如:
<Exec
IgnoreStandardErrorWarningFormat="true"
Command="PowerShell "$(ThingToDo)"" />
That sadly doesn't work:-
遗憾的是这不起作用:-
- if
ThingToDofails to parse, it fails silently - if
ThingToDois a script invocation that doesn't exist, it fails - if you want to propagate an
ERRORLEVELbased.cmdresult, it gets hairy - if you want to embed
"quotes in theThingToDo, it won't work
- 如果
ThingToDo解析失败,则静默失败 - 如果
ThingToDo是不存在的脚本调用,则失败 - 如果你想传播一个
ERRORLEVEL基于.cmd结果的结果,它会变得毛茸茸的 - 如果您想在 中嵌入
"引号ThingToDo,它将不起作用
So, what is the bullet proof way of running PowerShell from MSBuild supposed to be? Is there something I can PsGetto make everything OK?
那么,从 MSBuild 运行 PowerShell 的防弹方法应该是什么?有什么我可以PsGet使一切正常的东西吗?
Answer
回答
Weeeeelll, you could use something long winded like this until you find a better way:-
Weeeeeellll,你可以使用像这样冗长的东西,直到你找到更好的方法:-
<PropertyGroup>
<__PsInvokeCommand>powershell "Invoke-Command</__PsInvokeCommand>
<__BlockBegin>-ScriptBlock { $errorActionPreference='Stop';</__BlockBegin>
<__BlockEnd>; exit $LASTEXITCODE }</__BlockEnd>
<_PsCmdStart>$(__PsInvokeCommand) $(__BlockBegin)</_PsCmdStart>
<_PsCmdEnd>$(__BlockEnd)"</_PsCmdEnd>
</PropertyGroup>
And then 'all' you need to do is:
然后“所有”你需要做的是:
<Exec
IgnoreStandardErrorWarningFormat="true"
Command="$(_PsCmdStart)$(ThingToDo)$(_PsCmdEnd)" />
The single redeeming feature of this (other than trapping all error types I could think of), is that it works OOTB with any PowerShell version and any MSBuild version.
这个唯一的补偿功能(除了捕获我能想到的所有错误类型)是它可以与任何 PowerShell 版本和任何 MSBuild 版本一起使用。
I'll get my coat.
我去拿我的外套。
回答by Garrett Serack
With a bit of fun, I managed to come up with a fairly clean way of making this work:
带着一点乐趣,我设法想出了一种相当干净的方法来完成这项工作:
<?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>
Notes:
笔记:
- You can still use the standard Exec Task features! (see: https://msdn.microsoft.com/en-us/library/x8zx72cd.aspx)
if your powershell script needs to use < > or & characters, just place the contents in a CDATA wrapper:
<script2><![CDATA[ $(PowerShell) # your powershell code goes here! write-host "<<Hi mom!>>" ]]></script2>if you want return items to the msbuild script you can get them:
<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)" />
- 您仍然可以使用标准的 Exec Task 功能!(参见:https: //msdn.microsoft.com/en-us/library/x8zx72cd.aspx)
如果您的 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)" />
See! then you can use those items with another msbuild Task :D
看!然后您可以将这些项目与另一个 msbuild 任务一起使用:D

