2008-09-16 16 views
5

¿Alguien sabe de alguna buena tarea de MSBuild que ejecute un script de PowerShell y le pase diferentes parámetros?¿Alguna buena tarea de PowerShell MSBuild?

Pude encontrar B# .NET Blog: Invoking PowerShell scripts from MSBuild, pero estoy esperando algo más pulido.

Si no puedo encontrar nada, por supuesto solo seguiré puliendo el mío usando esa entrada de blog como titular.

+0

Usaría la publicación del blog como iniciador. Estamos trabajando con un consultor de Microsoft y es la publicación a la que nos remitió. Intenté la tarea Powershell MSBuild en codeplex, y se equivoca en un script mío de Powershell que funciona en la tarea creada por Bart De Smet. –

Respuesta

7

Es posible que también desee consultar Psake - un entorno de compilación basado en PowerShell.

9
4

Duplicate Question and Answer I Posted, aquí para la posteridad de cuando se ha votado a cerrado. La diferencia clave es que esta pregunta se limitó a ser OOTB y mi auto-respuesta se mantiene dentro de esa restricción.

Pregunta

PowerShell no parecen tener una forma fácil de activar con un comando arbitrario y luego brotan de análisis sintáctico y ejecución de errores de una manera que interactúa correctamente con las personas que llaman que no están PowerShell - por ejemplo, cmd.exe , TeamCity etc.

Mi pregunta es simple. ¿Cuál es la mejor manera para mí con OOTB MSBuild v4 y PowerShell v3 (abierto a sugerencias, no descartaría una tarea MSBuild preparada para producción adecuada, pero tendría que ser un poco más fuerte que sugerir "es fácil" tomando la muestra de PowerShell Task Factory y modificarlo y/o convertirlo en mantenedor/padre ") para ejecutar un comando (ya sea un segmento de script pequeño o (más comúnmente) una invocación de un script .ps1.

Creo que debería ser algo normal como:

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

que lamentablemente no funciona: -

  1. si ThingToDo no puede analizar, se produce un error en silencio
  2. si ThingToDo es una invocación de la escritura que no existe, se produce un error
  3. si desea propagar una ERRORLEVEL basado .cmd resultado, se pone peluda
  4. Si desea incrustar " cotizaciones en el ThingToDo, no va a funcionar

Así que, ¿cuál es el camino a prueba de balas de ejecutar PowerShell desde MSBuild supone que es? ¿Hay algo que pueda PsGet para que todo esté bien?

respuesta

Weeeeelll, usted podría utilizar algo de largo aliento como esto hasta que encuentre una mejor manera: -

<PropertyGroup> 
    <__PsInvokeCommand>powershell "Invoke-Command</__PsInvokeCommand> 
    <__BlockBegin>-ScriptBlock { $errorActionPreference='Stop';</__BlockBegin> 
    <__BlockEnd>; exit $LASTEXITCODE }</__BlockEnd> 
    <_PsCmdStart>$(__PsInvokeCommand) $(__BlockBegin)</_PsCmdStart> 
    <_PsCmdEnd>$(__BlockEnd)"</_PsCmdEnd> 
</PropertyGroup> 

Y entonces 'todo' lo que necesita hacer es:

<Exec 
    IgnoreStandardErrorWarningFormat="true" 
    Command="$(_PsCmdStart)$(ThingToDo)$(_PsCmdEnd)" /> 

La característica única de canje de esto (aparte de atrapar todos los tipos de error que pude pensar), es que funciona OOTB con cualquier versión de PowerShell y cualquier versión de MSBuild.

Voy a obtener mi abrigo.

0

Con un poco de diversión, me las arreglé para llegar a una forma bastante limpia de hacer este trabajo:

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

Notas:

  • puede seguir utilizando las características estándar de tareas Exec! (Ver: https://msdn.microsoft.com/en-us/library/x8zx72cd.aspx)
  • si el script de PowerShell necesita utilizar <> o & caracteres, basta con colocar el contenido en una envoltura CDATA:

    <script2><![CDATA[ $(PowerShell) 
        # your powershell code goes here! 
        write-host "<<Hi mom!>>" 
    ]]></script2> 
    
  • si desea que los elementos volver a la secuencia de comandos msbuild que pueda conseguirlos:

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

Ver! luego puede usar esos elementos con otra tarea de msbuild: D

Cuestiones relacionadas