Como fazer o Visual Studio copiar um arquivo DLL para o diretório de saída?

101

Eu tenho um projeto Visual Studio C ++ que depende de um arquivo DLL externo. Como posso fazer o Visual Studio copiar este arquivo DLL automaticamente para o diretório de saída (depurar / liberar) quando eu construir o projeto?

Esteira
fonte

Respostas:

90

Use uma ação pós-construção em seu projeto e adicione os comandos para copiar a DLL incorreta. A ação pós-construção é escrita como um script em lote.

O diretório de saída pode ser referenciado como $(OutDir). O diretório do projeto está disponível como $(ProjDir). Tente usar caminhos relativos onde aplicável, de modo que você possa copiar ou mover a pasta do seu projeto sem interromper a ação pós-construção.

Adrien Plisson
fonte
25
Também é importante ressaltar que ele pode definir o evento pós-construção via Projeto> Propriedades> Eventos de construção> Evento pós-construção.
Phil Booth
20
amostra: eyeung003.blogspot.com/2009/11/…
AntonioR
36
No caso de o link quebrar: "xcopy / y" $ (ProjectDir) *. Dll "" $ (OutDir) "
ás
Mudei o acima para como eu pessoalmente uso o comando em minhas instâncias. Isso vai; copia arquivos somente leitura que são bons com controle de origem e cria o diretório de destino (normalmente não necessário). -> xcopy "$ (ProjectDir) *. dll" "$ (OutDir)" / i / r / y
Comer no Joes de
8
Adicione o sinalizador / d a xCopy para evitar a recopia desnecessária de arquivos que não foram alterados no diretório de saída.
Zoey de
43

$ (OutDir) acabou sendo um caminho relativo no VS2013, então tive que combiná-lo com $ (ProjectDir) para obter o efeito desejado:

xcopy /y /d  "$(ProjectDir)External\*.dll" "$(ProjectDir)$(OutDir)"

BTW, você pode depurar facilmente os scripts adicionando 'echo' no início e observar o texto expandido na janela de saída do build.

Nesho Neshev
fonte
3
$ (TargetDir) pode substituir $ (ProjectDir) $ (OutDir) porque é uma combinação de ambos.
27
No meu caso, sem o / d, estava gerando um erro de acesso negado. Mas / d conforme a documentação é para a data. Não tenho certeza de qual é a conexão.
Ravi C
1
Adicionar / d evita sobrescrever se o arquivo de origem for mais antigo ou igual a um arquivo existente. O erro de acesso negado pode ocorrer se o destino estiver bloqueado por outro processo.
Rich Shealer de
7

Os detalhes na seção de comentários acima não funcionaram para mim (VS 2013) ao tentar copiar a dll de saída de um projeto C ++ para a pasta de lançamento e depuração de outro projeto C # dentro da mesma solução.

Tive que adicionar a seguinte ação pós-construção (clique com o botão direito no projeto que tem uma saída .dll) e propriedades -> propriedades de configuração -> eventos de compilação -> evento pós-compilação -> linha de comando

agora adicionei estas duas linhas para copiar a dll de saída para as duas pastas:

xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Release
xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Debug
SCBuergel.eth
fonte
5

(Esta resposta se aplica apenas a C #, não C ++, desculpe, eu interpretei mal a pergunta original)

Já passei por um inferno de DLL como este antes. Minha solução final foi armazenar as DLLs não gerenciadas na DLL gerenciada como recursos binários e extraí-las para uma pasta temporária quando o programa for iniciado e excluí-las quando for descartado.

Isto deveria fazer parte da infraestrutura .NET ou pinvoke, uma vez que é tão útil .... Ele torna sua DLL gerenciada fácil de gerenciar, tanto usando Xcopy ou como uma referência de projeto em uma solução Visual Studio maior. Depois de fazer isso, você não precisa se preocupar com eventos pós-construção.

ATUALIZAR:

Postei o código aqui em outra resposta https://stackoverflow.com/a/11038376/364818

Mark Lakata
fonte
1
Eu concordo, deve ser uma parte da estrutura (para vincular dlls estaticamente, etc.) - Vale a pena observar, armazenar a dll como um recurso e, em seguida, extraí-la em tempo de execução pode causar problemas em alguns ambientes corporativos (especialmente se eles tiverem software antivírus proativo).
BrainSlugs83 de
1

Adicione COPY integrado ao arquivo project.csproj :

  <Project>
    ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Debug\bin" SkipUnchangedFiles="false" />
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Release\bin" SkipUnchangedFiles="false" />
    </Target>
  </Project>
John_J
fonte
Há um bug de longo prazo no VS, use ProjectDir em vez de SolutionDir
John_J
0
xcopy /y /d  "$(ProjectDir)External\*.dll" "$(TargetDir)"

Você também pode se referir a um caminho relativo, o próximo exemplo encontrará a DLL em uma pasta localizada um nível acima da pasta do projeto. Se você tiver vários projetos que usam a DLL em uma única solução, isso colocará a origem da DLL em uma área comum acessível quando você definir qualquer um deles como o Projeto de inicialização.

xcopy /y /d  "$(ProjectDir)..\External\*.dll" "$(TargetDir)"

A /yopção copia sem confirmação. A /dopção verifica se um arquivo existe no destino e se ele copia apenas se a origem tiver um carimbo de data / hora mais recente que o destino.

Descobri que pelo menos em versões mais recentes do Visual Studio, como VS2109, $(ProjDir)é indefinido e teve que usar em seu $(ProjectDir)lugar.

Deixar de fora uma pasta de destino xcopydeve ser o padrão para o diretório de saída. É importante entender que a razão por $(OutDir)si só não ajuda.

$(OutDir), pelo menos nas versões recentes do Visual Studio, é definido como um caminho relativo para a pasta de saída, como bin/x86/Debug. Usá-lo sozinho como destino criará um novo conjunto de pastas a partir da pasta de saída do projeto. Ex: … bin/x86/Debug/bin/x86/Debug.

Combiná-lo com a pasta do projeto deve levá-lo ao lugar adequado. Ex: $(ProjectDir)$(OutDir).

No entanto $(TargetDir), fornecerá o diretório de saída em uma etapa.

Lista da Microsoft de macros MSBuild para versões atuais e anteriores do Visual Studio

Rich Shealer
fonte