Какие-нибудь хорошие задачи PowerShell MSBuild? - PullRequest
5 голосов
/ 17 сентября 2008

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

Мне удалось найти B # .NET Blog: вызов сценариев PowerShell из MSBuild , но я надеюсь на что-то более отточенное.

Если я не могу найти что-либо, я, конечно, просто продолжу и отшлифую свою собственную, используя этот пост в блоге.

Ответы [ 4 ]

7 голосов
/ 17 сентября 2008

Возможно, вы также захотите взглянуть на Psake - среду сборки на основе PowerShell.

4 голосов
/ 10 октября 2012

Дубликат вопроса и ответа, который я опубликовал , здесь для потомков, когда голосование было закрыто. Ключевое отличие состоит в том, что этот вопрос был ограничен до OOTB , и мой ответ на вопрос остается в рамках этого ограничения.

Вопрос

Похоже, у Powershell нет простого способа вызвать его с помощью произвольной команды, а затем вызвать ошибки синтаксического анализа и выполнения таким образом, чтобы правильно взаимодействовать с вызывающими, не являющимися PowerShell, - например, cmd.exe, TeamCity и т. Д.

Мой вопрос прост. Как мне лучше всего использовать OOTB MSBuild v4 и PowerShell v3 (открыт для предложений - не исключаю подходящую для производства задачу MSBuild, но она должна быть немного сильнее, чем предполагать: «это просто» - взяв пример PowerShell Task Factory и настроить его и / или стать его сопровождающим / родительским ") для запуска команды (либо небольшого сегмента скрипта, либо (чаще всего) вызова скрипта .ps1.

Я думаю, это должно быть что-то нормальное, вроде:

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

К сожалению, это не работает: -

  1. если ThingToDo не удается разобрать, он молча завершается
  2. если ThingToDo - это вызов сценария, который не существует, он завершается ошибкой
  3. Если вы хотите распространить ERRORLEVEL основанный .cmd результат, он становится волосатым
  4. , если вы хотите вставить " кавычки в ThingToDo, он не будет работать

Итак, каким должен быть пуленепробиваемый способ запуска PowerShell из MSBuild? Могу ли я что-нибудь сделать PsGet , чтобы все было в порядке?

Ответ

Ну-а-а-а, вы можете использовать что-то длинное, как это, пока не найдете лучший способ: -

<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)" />

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

Я возьму свое пальто.

1 голос
/ 09 декабря 2016

С небольшой забавой мне удалось придумать довольно чистый способ сделать эту работу:

<?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>

Примечания:

  • Вы все еще можете использовать стандартные функции 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)" /> 
    

См! тогда вы можете использовать эти предметы с другой задачей msbuild: D

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