【问题标题】:Any good PowerShell MSBuild tasks?任何好的 PowerShell MSBuild 任务?
【发布时间】:2010-09-09 20:02:40
【问题描述】:

有人知道任何可以执行 PowerShell 脚本并传递不同参数的好的 MSBuild 任务吗?

我找到了B# .NET Blog: Invoking PowerShell scripts from MSBuild,但我希望能找到更精致的东西。

如果我找不到任何东西,我当然会继续使用该博客文章作为入门来完善我自己的内容。

【问题讨论】:

  • 我将使用博客文章作为入门。我们正在与微软的一位顾问合作,这是他向我们推荐的职位。我在 codeplex 上尝试了 Powershell MSBuild 任务,但它在我的一个 Powershell 脚本上出错,该脚本在 Bart De Smet 编写的任务中工作。

标签: visual-studio powershell msbuild


【解决方案1】:

您可能还想查看Psake - 基于 PowerShell 的构建环境。

【讨论】:

    【解决方案2】:

    【讨论】:

    • Nicer 将是 Microsoft 提供的 PowerShell 功能子集(不希望不受限制的副作用与项目文件的主要声明性质和 msbuild 的更改检测相混淆)。现有的Property functions 似乎是一个开始(至少它们有 PowerShell 语法)
    【解决方案3】:

    Duplicate Question and Answer I Posted,这里是为了后代投票关闭。主要区别在于,这个问题被限制为 OOTB,而我的自我回答保持在该限制范围内。

    问题

    Powershell 似乎没有一种简单的方法来使用任意命令触发它,然后以与非 PowerShell 的调用者正确互操作的方式冒泡解析和执行错误 - 例如,cmd.exeTeamCity等等

    我的问题很简单。使用 OOTB MSBuild v4 和 PowerShell v3 对我来说最好的方法是什么(接受建议 - 不会排除适合生产的 MSBuild 任务,但它需要比建议“这很容易 - 使用 PowerShell 任务工厂示例和调整它和/或成为它的维护者/父”)以运行命令(一个小脚本段,或(最常见的).ps1 脚本的调用。

    我认为它应该是正常的,例如:

    <Exec 
      IgnoreStandardErrorWarningFormat="true"
      Command="PowerShell &quot;$(ThingToDo)&quot;" />
    

    遗憾的是,这行不通:-

    1. 如果ThingToDo 解析失败,则静默失败
    2. 如果ThingToDo 是不存在的脚本调用,则会失败
    3. 如果你想传播基于 ERRORLEVEL.cmd 结果,它会变得很麻烦
    4. 如果您想在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。

    我去拿我的外套。

    【讨论】:

      【解决方案4】:

      有点乐趣,我设法想出了一个相当干净的方法来完成这项工作:

      <?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 -&amp; 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>
      

      注意事项:

      • 您仍然可以使用标准的执行任务功能! (见: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)" /> 
        

      看!那么您可以将这些项目与另一个 msbuild 任务一起使用:D

      【讨论】:

      • 我喜欢。我已经看到由 Walid Toumi 在 msbuild 之外完成的 similar things (并使用它们取得了良好的效果)。感谢您花时间调试那些挑剔的东西。这个概念很简单,我猜想让它真正发挥作用可能还没有(或者你可能是幸运或天才:-) 在我的环境中,我需要添加 -executionpolicy remotesigned。
      猜你喜欢
      • 1970-01-01
      • 2016-09-08
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 2011-04-26
      • 1970-01-01
      • 2013-02-14
      相关资源
      最近更新 更多