Cómo ejecutar eventos posteriores a la compilación de Visual Studio solo para la compilación de depuración

592

¿Cómo puedo limitar mis eventos posteriores a la compilación para que se ejecuten solo para un tipo de compilación?

Estoy usando los eventos para copiar archivos DLL en un directorio virtual local de IIS, pero no quiero que esto suceda en el servidor de compilación en modo de lanzamiento.

JC
fuente

Respuestas:

746

Los eventos previos y posteriores a la compilación se ejecutan como un script por lotes. Puede hacer una declaración condicional en$(ConfigurationName) .

Por ejemplo

if $(ConfigurationName) == Debug xcopy something somewhere
Joseph Daigle
fuente
77
extraño, tal vez soy solo yo, pero intenté agregar la condición if, y ahora recibo este error - error salido con el código 255
Michael L
101
Descubrí que todo el comando debe estar en una línea o "saldrás con el código 255"
Robin Minto
77
También puede usar gotos / etiquetas para una solución más completa (vea mi respuesta del 24 de julio)
CestLaGalere
11
y se puede utilizar soportes con el comando if (véase mi respuesta para un ejemplo)
gbjbaanb
1
Debe usar "xcopy / Y", para que el archivo se sobrescriba en el directorio de destino.
Matthias
521

Para su información, no necesita usar goto. El comando shell IF se puede usar con corchetes:

if $(ConfigurationName) == Debug (
  copy "$(TargetDir)myapp.dll" "c:\delivery\bin" /y
  copy "$(TargetDir)myapp.dll.config" "c:\delivery\bin" /y
) ELSE (
  echo "why, Microsoft, why".
)
gbjbaanb
fuente
6262
También puedo agregar, para tener cuidado con el paréntesis de apertura que debe seguir inmediatamente la declaración if, como si estuviera en la siguiente línea se generará un código de error
wonea
37
Use "$(ConfigurationName)"(observe las comillas) si obtiene el código de error 255
jgauffin
20
tenga en cuenta que si usa "" alrededor de $ (ConfigurationName), también necesita comillas alrededor de la palabra Depuración: las instrucciones IF del comando de shell son muy ... literales ... cuando se trata de comparaciones de cadenas.
gbjbaanb
55
Nota: Para deshacerme del 255, tuve que usar "" alrededor de $ (ConfigurationName) Y eliminar espacios alrededor de la condición, por ejemplo si "$ (ConfigurationName)" == "Release" <- Sin espacios alrededor ==
fhilton
15
En mi caso con Visual Studio 2017 $(ConfigurationName)está vacío (línea de comando del evento posterior a la compilación). if "$(Configuration)" == "Debug"trabajó para mi. Por cierto, si quieres hacer algo en todas las demás configuraciones, úsalo if NOT "$(Configuration)" == "Debug".
Ralf Hundewadt
125

Agregue su evento de creación de publicaciones como de costumbre. Luego guarde su proyecto, ábralo en el Bloc de notas (o su editor favorito) y agregue la condición al grupo de propiedades PostBuildEvent. Aquí hay un ejemplo:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <PostBuildEvent>start gpedit</PostBuildEvent>
</PropertyGroup>
Franci Penov
fuente
55
Esto funciona, pero lo obliga a realizar todo su trabajo de diseño para los eventos en el origen del archivo del proyecto. Otras declaraciones de eventos de compilación condicionales también se ocultan del IDE.
Joseph Daigle
3
Debo decir que esta es la mejor respuesta para mí, el método preferido simplemente no funcionó.
Michael L
8
No necesita abrirlo en el Bloc de notas, puede permanecer en Visual Studio. Puede hacer clic derecho en el archivo del proyecto, hacer clic en "Descargar proyecto", luego hacer clic derecho nuevamente y hacer clic en "Editar". Ahora puede editar el archivo {{csproj}} con colores de sintaxis. Haga clic derecho nuevamente, pero ahora haga clic en "Recargar proyecto" para volver a cargar.
Abel
1
Este enfoque no expandió las macros en el comando PostBuildEvent en sí cuando lo probé. cd "$(ProjectDir)"expandido a cd "".
Darryl
3
En VS 2017 también puedes hacer esto con <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$(ConfigurationName) == Debug"> <Exec Command="your command"/></Target>. Las variables macro y todo funcionan normalmente.
SC
106

Alternativamente (dado que los eventos se colocan en un archivo por lotes y luego se llaman), use lo siguiente (en el cuadro de evento Generar, no en un archivo por lotes):

if $(ConfigurationName) == Debug goto :debug

:release
signtool.exe ....
xcopy ...

goto :exit

:debug
' Debug items in here

:exit

De esta manera, puede tener eventos para cualquier configuración, y aún así administrarlo con las macros en lugar de tener que pasarlos a un archivo por lotes, recuerde que %1es $(OutputPath), etc.

CestLaGalere
fuente
66
Si tiene la oportunidad de ver parte de su código en el reflector, el compilador transforma muchas declaraciones de cambio / caso en goto's.
StingyJack
10
La mayoría de los compiladores traducen el código a instrucciones más simples, como goto. Y la ingeniería inversa no puede juntar instrucciones más simples en las "agradables" instrucciones más complejas que preferiría ver. No veo cómo Microsoft nos obliga a usar goto, o cómo esto es relevante para esta publicación.
TamusJRoyce
1
@StingyJack: si miras el código compilado, verás que todo se convierte en instrucciones JMP :) No me importa lo que haga el compilador debajo de las cubiertas, siempre que pueda escribir un código agradablemente legible. (no es que usar goto ocasionalmente no sea muy fácil de leer)
gbjbaanb
Si pongo mis comandos posteriores a la compilación dentro de un lote, aparece este mensaje de error cuando presiono compilar:Error 1 The command "C:\MyProject\postbuild.bat" exited with code 99. MyProject
Sebastian
44
si lo desea, puede eliminar ify usargoto :$(ConfigurationName)
Calimero100582
15

Visual Studio 2015: la sintaxis correcta es (mantenerla en una línea):

if "$(ConfigurationName)"=="My Debug CFG" ( xcopy "$(TargetDir)test1.tmp" "$(TargetDir)test.xml" /y) else ( xcopy "$(TargetDir)test2.tmp" "$(TargetDir)test.xml" /y)

No hay error 255 aquí.

Eric Bole-Feysot
fuente
3
manténgalo en una línea
Eric Bole-Feysot
Trabajando bien Tks
Vinicius Gonçalves
1
Tu técnica condicional funcionó mejor para mí. Sin embargo, esto funcionó aún mejor sin condicionales y es mucho más conciso. copie "$ (ProjectDir) \ .. \ $ (ConfigurationName) \ MyFileName" "$ (TargetDir)"
shawn1874
1
Su script es correcto, pero mi script permite copiar diferentes archivos para diferentes configuraciones.
Eric Bole-Feysot
8

A partir de Visual Studio 2019, el .csprojformato moderno admite agregar una condición directamente en el Targetelemento:

<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Debug'">
    <Exec Command="nswag run nswag.json" />
</Target>

La interfaz de usuario no proporciona una manera de configurar esto, pero parece dejar el Configurationatributo de forma segura si realiza cambios a través de la interfaz de usuario.

Daniel Earwicker
fuente
Esto funcionó para mí en VS 2019, ¡gracias!
BrandoTheBrave
Esto realmente merece ser más alto, también deberían actualizar la interfaz de usuario para permitirle marcar la configuración de compilación o al menos agregar la condición de las propiedades de csproj.
DeadlyChambers
4

Puede pasar el nombre de la configuración al script posterior a la compilación y verificarlo allí para ver si debe ejecutarse.

Pase el nombre de la configuración con $(ConfigurationName) .

Verificarlo se basa en cómo está implementando el paso posterior a la compilación: será un argumento de línea de comandos.

Lou Franco
fuente
-1

Esto funciona para mí en Visual Studio 2015.

Copio todos los archivos DLL de una carpeta ubicada en una carpeta de biblioteca en el mismo nivel que mi carpeta de solución en el directorio de destino del proyecto que se está creando.

Usando una ruta relativa desde mi directorio de proyecto y subiendo la estructura de carpetas dos pasos con .. \ .. \ lib

MySolutionFolder
.... MyProject
Lib

if $(ConfigurationName) == Debug (
xcopy /Y "$(ProjectDir)..\..\lib\*.dll" "$(TargetDir)"
) ELSE (echo "Not Debug mode, no file copy from lib")
Jaan Marks
fuente
-2

Al igual que cualquier configuración de proyecto, los eventos se pueden configurar por Configuración. Simplemente seleccione la configuración que desea cambiar en el menú desplegable del cuadro de diálogo Páginas de propiedades y edite el paso posterior a la compilación.

Harald Scheirich
fuente
10
Los eventos de compilación no son específicos de ninguna configuración cuando se crean en el IDE.
Joseph Daigle
1
Tampoco funciona en VS2015. No configurable por configuración.
willem
2
Esto solo se aplica a proyectos C ++ en Visual Studio, no C #
bytecode77
-3

En Visual Studio 2012 tienes que usar (creo que también en Visual Studio 2010)

if $(Configuration) == Debug xcopy

$(ConfigurationName) fue catalogado como una macro, pero no fue asignado.

Ingrese la descripción de la imagen aquí

Compare: Macros para compilar comandos y propiedades

mawl
fuente
77
Desea usar ConfigurationName. Esta imagen es ... realmente difícil de entender con todo el desenfoque.
Stealth Rabbi