Visual Studio: ¿varios comandos posteriores a la compilación?

101

Visual Studio 2008 me permite declarar un comando y adjuntarlo al evento posterior a la compilación de un proyecto. Como muchos desarrolladores, lo uso regularmente para copiar archivos al directorio de salida de la aplicación.

Estoy trabajando en un proyecto en el que necesito copiar archivos de dos lugares diferentes a dos destinos diferentes, todo dentro de un solo proyecto. En otras palabras, necesito invocar dos comandos xcopy diferentes desde el mismo evento posterior a la compilación. Parece que el evento posterior a la compilación solo tomará un solo comando, y que si necesito invocar varios comandos, tendré que poner los comandos en un archivo * .bat y llamarlo desde el evento posterior a la compilación.

¿Es eso correcto o hay una forma más sencilla de invocar dos comandos desde el evento posterior a la compilación? Gracias de antemano por tu ayuda.

David Veeneman
fuente

Respuestas:

124

Puede escribir tantos comandos posteriores a la compilación como desee. Solo sepárelos por líneas nuevas.

Aquí tienes un ejemplo de uno de mis proyectos.

Línea de comandos de evento posterior a la construcción

womp
fuente
3
Incluir una captura de pantalla solo es útil si tiene la intención de alojarla para siempre.
Amandalishus
1
@ OWenJ23 ... o 'imageshack' en este caso;)
Anthony Walsh
28
A pesar de estar en líneas separadas, mis comandos se ejecutan juntos como si estuvieran en una sola línea.
Trevor
6
Desafortunadamente, parece que al menos VS2015 no informa un error si falla uno de los comandos intermedios ... informa el resultado del último comando como resultado del paso posterior a la compilación.
Johannes S.
3
Parece que esto funciona desde dentro de Visual Studio, pero no es compatible si usa MsBuild en una máquina de compilación TFS. MsBuild elimina los saltos de línea y luego falla el comando debido a una mala sintaxis.
Jeff B
107

Importante: al ejecutar un archivo por lotes, debe utilizar la instrucción "call" para que se ejecuten las siguientes líneas. Si no usa "call", la ejecución pasa al .bat y no regresa a las siguientes líneas. Igual que en el indicador de DOS.

p.ej:

call MyBatch1.bat
call MyBatch2.bat
huha
fuente
3
Este consejo se aplica a los comandos grunt y npm ya que ambos se ejecutan en archivos por lotes (grunt.cmd y npm.cmd).
Matt Varblow
16

Hay otra opción: puedes separar los comandos con &&. P.ej

copy $(TargetPath) d:\folder1 && copy $(TargetPath) d:\folder2

Esto no es exactamente lo mismo que separar con nuevas líneas: con &&, si el comando anterior falló, el siguiente comando no se ejecutará.

La separación por nuevas líneas es más fácil de leer, por lo que debería preferirla. Sin embargo, conozco al menos un caso cuando &&es útil. Es el escenario, cuando usa hojas de propiedades para tener diferentes pasos posteriores a la construcción en diferentes máquinas. VS 2008 no permite configurar PostBuildStep en las hojas de propiedades directamente, pero puede agregar una macro de usuario con su comando y llamarla desde la configuración principal del proyecto. Una macro es de una sola línea, por lo que puede utilizar &&para tener varios comandos allí.

Corcel
fuente
11

Cada comando debe estar en una línea separada. Sin embargo, lo que encontré es que si hay un error al ejecutar uno de esos comandos, toda la compilación posterior falla, por lo que deberá probar cada comando posterior a la compilación uno a la vez para depurar.

Lisa
fuente
2
"xcopy / f" mostrará el nombre de archivo de origen y destino completo, que se imprimirá antes del error, lo que hará que varios comandos xcopy sean más fáciles de diagnosticar que varios comandos de copia.
yoyo
9

Separando los comandos con & o && o; no funciona en VS2017. No puedo creer que una funcionalidad tan simple no esté disponible en VS2017. Visual Studio intenta ejecutar todo el texto en la ventana del evento posterior a la compilación como una cadena. La única opción para mí ahora es crear un script por lotes que no me gusta particularmente.

Indra
fuente
1
Separar los comandos con && me funciona en VS2017. Especificar cada comando en una línea separada en el editor VS2017 no me funciona.
codesniffer
5

Agregando a la respuesta de womp :

Si tiene varias hojas de propiedades con algo que hacer en el mismo evento de compilación, puede hacer lo siguiente para encadenar los comandos:

%(Command)
echo foo

donde se %(Command)expande al valor anterior del comando.

Personalmente, hago esto para todos los eventos de compilación, incluso si actualmente no tengo comandos heredados, porque esto garantiza que no habrá problemas si agrego hojas de propiedades más adelante.

Max Truxa
fuente
1
Esto también funciona con el paso de compilación personalizado. Además, la ejecución de una exitinstrucción por lotes en cualquier parte de la cadena hace que la cadena se interrumpa. De hecho, exit 1hace que la compilación falle, mientras que exit 0simplemente anula el paso y la compilación continúa.
Martin Connell
3

En Visual Studio 2017 puede hacer esto:

<PostBuildEvent>
    <Command>
        copy $(TargetPath) $(SolutionDIr)\bin1
        copy $(TargetPath) $(SolutionDIr)\bin2
    </Command>
</PostBuildEvent>
Jonathan Weesner
fuente
1
Edité el .csproj y agregué <Command> </Command> alrededor de mis dos comandos de eventos posteriores a la compilación. Eso no pareció funcionar. Cuando miré en Eventos de compilación en Visual Studio, tenía el <Command> </Command> alrededor de los dos comandos, pero dio un error de compilación: El comando "<Command xmlns =" ​​.. "> command1 command2 </Command>" salió con el código 255.
Jimmy
1

El enfoque sugerido por womp funciona en Visual Studio 2015/2017 (Windows), pero no funciona en Visual Studio para Mac (Vista previa), que parece ejecutar solo el primero de los comandos. El único enfoque que encontré funcionando en las versiones de Visual Studio para Mac y Windows fue encadenar 2 comandos de MSBuild:

<Target Name="AfterResolveReferences">
<Exec Command="path\MyFirstCommand.exe -parameters" />
</Target>
<Target Name="MySecondCommand" AfterTargets="AfterResolveReferences" >
<Exec Command="path\MySecondCommand.exe -parameters" />
</Target>

El ejemplo anterior usa el evento "AfterResolveReferences" pero obviamente también debería funcionar para el evento PostBuild.

Crulex
fuente
1

No existe una buena solución para este problema. La idea de llamada hace que se ejecuten otros scripts. He notado que la detección de errores no funcionará. Ponga 'exit / b 1' en FailMe.cmd El uso 'call FailMe.cmd' en los pasos posteriores a la compilación. ¿Notas que la construcción no falla? Estoy usando VS 2017 construyendo un proyecto C #. Ahora inténtelo con 'FailMe.cmd' La compilación ahora informa de un error.

Por lo tanto, es mejor que use un solo script, si el informe de errores es importante.

Richard Meadows
fuente
-4

Simplemente prefija "llamada" a su secuencia de comandos por lotes. De modo que las declaraciones debajo del script por lotes también se ejecutan después de devolver la llamada desde el script por lotes.

call Script1.cmd
call Script2.bat
msKing
fuente