Visual Studio: Vários comandos pós-compilação?

101

O Visual Studio 2008 me permite declarar um comando e anexá-lo ao evento pós-construção de um projeto. Como muitos desenvolvedores, eu o uso regularmente para copiar arquivos para o diretório de saída do aplicativo.

Estou trabalhando em um projeto onde preciso xcopy arquivos de dois lugares diferentes para dois destinos diferentes, tudo dentro de um único projeto. Em outras palavras, preciso invocar dois comandos xcopy diferentes do mesmo evento pós-compilação. Parece que o evento pós-compilação levará apenas um único comando e, se eu precisar invocar vários comandos, terei que colocar os comandos em um arquivo * .bat e chamá-lo do evento pós-compilação.

Isso está correto ou existe uma maneira mais simples de invocar dois comandos do evento pós-compilação? Agradeço antecipadamente por sua ajuda.

David Veeneman
fonte

Respostas:

124

Você pode digitar quantos comandos de pós-compilação desejar. Basta separá-los por novas linhas.

Aqui está um exemplo de um dos meus projetos.

Linha de comando do evento pós-construção

womp
fonte
3
Incluir uma captura de tela só é útil se você pretende hospedá-la para sempre.
Amandalishus,
1
@ OWenJ23 ... ou 'imageshack' neste caso;)
Anthony Walsh
28
Apesar de estarem em linhas separadas, meus comandos estão sendo executados juntos como se estivessem em uma única linha.
Trevor
6
Infelizmente, parece que pelo menos o VS2015 não relata um erro se um dos comandos intermediários falhar ... ele relata o resultado do último comando como resultado da etapa de pós-compilação.
Johannes S.
3
Parece que isso funciona de dentro do Visual Studio - mas não é compatível se você usar o MsBuild em uma máquina de compilação TFS. MsBuild remove as quebras de linha e, em seguida, falha o comando devido a sintaxe incorreta.
Jeff B
107

Importante: Ao executar um arquivo em lote, você deve usar a instrução "call" para que as seguintes linhas sejam executadas. Se você não usar "call", a execução vai para o .bat e não volta para as linhas seguintes. Igual ao prompt do DOS.

por exemplo:

call MyBatch1.bat
call MyBatch2.bat
huha
fonte
3
Essa dica se aplica aos comandos grunt e npm, pois ambos são executados em arquivos em lote (grunt.cmd e npm.cmd).
Matt Varblow
16

Existe outra opção: você pode separar os comandos com &&. Por exemplo

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

Isso não é exatamente o mesmo que separar com novas linhas: com &&, se o comando anterior falhar, o próximo commant não será executado.

Separar por novas linhas é mais fácil de ler, então você deve preferir. No entanto, conheço pelo menos um caso em que &&é útil. É o cenário, quando você usa folhas de propriedades, para ter diferentes etapas de pós-construção em máquinas diferentes. O VS 2008 não permite definir PostBuildStep diretamente nas folhas de propriedades, mas você pode adicionar uma macro de usuário com seu comando e chamá-la a partir das configurações principais do projeto. Uma macro é uma linha única, então você pode usar &&para ter vários comandos lá.

Corcel
fonte
11

Cada comando deve estar em uma linha separada. O que descobri, porém, é que se houver um erro ao executar um desses comandos, todo o pós-compilação falhará e, portanto, você precisará tentar cada comando pós-compilação, um de cada vez, para depurar.

Lisa
fonte
2
"xcopy / f" mostrará o nome completo do arquivo de origem e destino, que será impresso antes da falha, tornando mais fácil o diagnóstico de vários comandos xcopy do que vários comandos de cópia.
yoyo
9

Separando os comandos com & ou && ou; não funciona no VS2017. Não consigo acreditar que uma funcionalidade tão simples não esteja disponível no VS2017. O Visual Studio tenta executar todo o texto na janela de evento pós-construção como uma string. A única opção para mim agora é criar um script em lote do qual não gosto particularmente.

Indra
fonte
1
Separar os comandos com && funciona para mim no VS2017. Especificar cada comando em uma linha separada no editor VS2017 não funciona para mim.
codesniffer
5

Somando-se womp 's resposta :

Se você tiver várias folhas de propriedades com algo para fazer no mesmo evento de construção, pode fazer o seguinte para encadear os comandos:

%(Command)
echo foo

onde se %(Command)expande para o valor anterior do comando.

Pessoalmente, faço isso para todos os eventos de construção, mesmo que atualmente não tenha comandos herdados, porque isso garante que não haverá problemas se eu adicionar folhas de propriedades posteriormente.

Max Truxa
fonte
1
Isso também funciona com a Etapa de compilação personalizada. Além disso, a execução de uma exitinstrução batch em qualquer lugar ao longo da cadeia faz com que a cadeia seja abortada. De fato, exit 1faz com que a construção falhe enquanto exit 0apenas aborta a etapa e a construção continua.
Martin Connell
3

No Visual Studio 2017, você pode fazer isso:

<PostBuildEvent>
    <Command>
        copy $(TargetPath) $(SolutionDIr)\bin1
        copy $(TargetPath) $(SolutionDIr)\bin2
    </Command>
</PostBuildEvent>
Jonathan Weesner
fonte
1
Editei o .csproj e adicionei <Command> </Command> aos meus dois comandos de evento pós-construção. Isso não pareceu funcionar. Quando eu olhei em Build Events no Visual Studio, ele tinha o <Command> </Command> em torno dos dois comandos, mas deu um erro de build: O comando "<Command xmlns =" ​​.. "> command1 command2 </Command>" saiu com o código 255.
Jimmy,
1

A abordagem sugerida por womp funciona no Visual Studio 2015/2017 (Windows), mas não funciona no Visual Studio para Mac (Preview), que parece executar apenas o primeiro dos comandos. A única abordagem que encontrei funcionando nas versões Mac e Windows do Visual Studio foi encadear 2 comandos MSBuild:

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

O exemplo acima usa o evento "AfterResolveReferences", mas obviamente também deve funcionar para o evento PostBuild.

Crulex
fonte
1

Não existe uma boa solução para este problema. A ideia de chamada faz com que outros scripts sejam executados. Percebi que a detecção de erros não funciona. Coloque 'exit / b 1' em FailMe.cmd Use 'call FailMe.cmd' nas etapas de pós-compilação. Observe que a construção não falha? Estou usando o VS 2017 para construir um projeto C #. Agora tente com 'FailMe.cmd' A compilação agora relata um erro.

Portanto, talvez seja melhor usar apenas um único script, se o relatório de erros for importante.

Richard Meadows
fonte
-4

Basta prefixar "chamada" em seu script em lote. Portanto, as instruções abaixo do script em lote também são executadas após o retorno da chamada do script em lote.

call Script1.cmd
call Script2.bat
msKing
fonte