Bagaimana cara membuat Visual Studio menyalin file DLL ke direktori output?

101

Saya memiliki proyek Visual Studio C ++ yang mengandalkan file DLL eksternal. Bagaimana cara membuat Visual Studio menyalin file DLL ini secara otomatis ke direktori keluaran (debug / rilis) ketika saya membangun proyek?

Tikar
sumber

Jawaban:

91

Gunakan tindakan pasca pembuatan dalam proyek Anda, dan tambahkan perintah untuk menyalin DLL yang melanggar. Tindakan pasca-pembuatan ditulis sebagai skrip batch.

Direktori keluaran dapat dirujuk sebagai $(OutDir). Direktori proyek tersedia sebagai $(ProjDir). Coba gunakan jalur relatif jika memungkinkan, sehingga Anda dapat menyalin atau memindahkan folder proyek tanpa merusak tindakan pasca-pembuatan.

Adrien Plisson
sumber
26
Juga perlu diperhatikan bahwa dia dapat menyetel acara pasca-pembangunan melalui Project> Properties> Build Events> Post-Build Event.
Phil Booth
37
Jika tautan rusak: "xcopy / y" $ (ProjectDir) *. Dll "" $ (OutDir) "
ace
Saya mengubah hal di atas menjadi cara saya menggunakan perintah secara pribadi dalam contoh saya. Ini akan; salin file read-only yang baik dengan kontrol sumber, dan buat direktori target (biasanya tidak diperlukan). -> xcopy "$ (ProjectDir) *. dll" "$ (OutDir)" / i / r / y
Makan di Joes
8
Tambahkan / d flag ke xCopy untuk mencegah penyalinan ulang yang tidak perlu dari file yang tidak berubah di direktori output.
Zoey
44

$ (OutDir) ternyata merupakan jalur relatif di VS2013, jadi saya harus menggabungkannya dengan $ (ProjectDir) untuk mencapai efek yang diinginkan:

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

BTW, Anda dapat dengan mudah men-debug skrip dengan menambahkan 'echo' di awal dan mengamati teks yang diperluas di jendela keluaran build.

Nesho Neshev
sumber
3
$ (TargetDir) dapat menggantikan $ (ProjectDir) $ (OutDir) karena ini adalah kombinasi keduanya.
person27
Dalam kasus saya tanpa / d itu melontarkan kesalahan Access Denied. Tapi / d sesuai dokumentasi untuk tanggal. Tidak yakin apa hubungannya.
Ravi C
1
Menambahkan / d mencegah penimpaan jika file sumber lebih lama atau sama dengan file yang sudah ada. Kesalahan akses ditolak dapat terjadi jika target dikunci oleh proses lain.
Rich Shealer
7

Detail di bagian komentar di atas tidak berfungsi untuk saya (VS 2013) ketika mencoba menyalin dll keluaran dari satu proyek C ++ ke folder rilis dan debug dari proyek C # lain dalam solusi yang sama.

Saya harus menambahkan post build-action berikut (klik kanan pada proyek yang memiliki output .dll) lalu properti -> properti konfigurasi -> build event -> post-build event -> command line

sekarang saya menambahkan dua baris ini untuk menyalin dll keluaran ke dalam dua folder:

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

(Jawaban ini hanya berlaku untuk C # bukan C ++, maaf saya salah membaca pertanyaan aslinya)

Saya telah melalui DLL neraka seperti ini sebelumnya. Solusi terakhir saya adalah menyimpan DLL yang tidak dikelola di DLL yang dikelola sebagai sumber daya biner, dan mengekstraknya ke folder sementara saat program diluncurkan dan menghapusnya saat dibuang.

Ini harus menjadi bagian dari infrastruktur .NET atau pinvoke, karena sangat berguna .... Itu membuat DLL terkelola Anda mudah dikelola, baik menggunakan Xcopy atau sebagai referensi Proyek dalam solusi Visual Studio yang lebih besar. Setelah Anda melakukan ini, Anda tidak perlu khawatir tentang acara pasca-pembangunan.

MEMPERBARUI:

Saya memposting kode di sini di jawaban lain https://stackoverflow.com/a/11038376/364818

Mark Lakata
sumber
1
Saya setuju, itu harus menjadi bagian dari kerangka kerja (untuk menghubungkan dll secara statis, dll.) - Perlu dicatat, menyimpan dll sebagai sumber daya dan kemudian mengekstraknya saat runtime dapat menyebabkan masalah di beberapa lingkungan perusahaan (terutama jika mereka memiliki cukup perangkat lunak anti-virus proaktif).
BrainSlugs83
1

Tambahkan COPY bawaan di file 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
sumber
Ada bug jangka panjang pada VS, harap gunakan ProjectDir daripada SolutionDir
John_J
0
xcopy /y /d  "$(ProjectDir)External\*.dll" "$(TargetDir)"

Anda juga dapat merujuk ke jalur relatif, contoh berikutnya akan menemukan DLL dalam folder yang terletak satu tingkat di atas folder proyek. Jika Anda memiliki beberapa proyek yang menggunakan DLL dalam satu solusi, ini menempatkan sumber DLL di area umum yang dapat dijangkau ketika Anda menetapkan salah satu dari mereka sebagai Proyek Startup.

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

The /ysalinan pilihan tanpa konfirmasi. The /dpilihan pemeriksaan untuk melihat apakah file ada di target dan jika tidak hanya salinan jika sumber memiliki timestamp yang lebih baru dari target.

Saya menemukan bahwa setidaknya versi Visual Studio yang lebih baru, seperti VS2109, $(ProjDir)tidak ditentukan dan harus digunakan $(ProjectDir)sebagai gantinya.

Meninggalkan folder target di xcopyharus default ke direktori output. Itu penting untuk memahami alasan $(OutDir)saja tidak membantu.

$(OutDir), setidaknya dalam versi terbaru Visual Studio, ditetapkan sebagai lintasan relatif ke folder keluaran, seperti bin/x86/Debug. Menggunakannya sendiri sebagai target akan membuat sekumpulan folder baru mulai dari folder keluaran proyek. Ex: … bin/x86/Debug/bin/x86/Debug.

Menggabungkannya dengan folder proyek akan membawa Anda ke tempat yang tepat. Ex: $(ProjectDir)$(OutDir).

Namun $(TargetDir)akan memberikan direktori keluaran dalam satu langkah.

Daftar makro MSBuild Microsoft untuk versi Visual Studio saat ini dan sebelumnya

Rich Shealer
sumber