Salin ke Direktori Output menyalin struktur folder tetapi hanya ingin menyalin file

87

Saya memiliki VS2008 Saya ingin menyalin file tertentu dari direktori ke /bin/folder saya . Saya telah mengatur file (terletak di /common/browserhawk/) ke "Salin ke Direktori Output". Namun, itu juga menyalin struktur folder: file akan disalin ke/bin/common/browserhawk/

Bagaimana cara mendapatkan file-file ini untuk disalin /bin/? Saya tidak ingin menyimpannya di root situs web agar dapat disalin dengan benar.

Pertanyaan Terkait: Visual Studio menambahkan .dll dan .pdb ke proyek setelah kompilasi

Steve Wright
sumber

Jawaban:

59

Anda dapat menambahkan Post Build Event untuk menyalin file.
Buka properti proyek, tab Peristiwa Build dan tambahkan yang berikut ini ke baris perintah Post-build event:

copy "$(ProjectDir)\common\browserhawk\*.*" "$(TargetDir)"

Pastikan untuk menyertakan tanda kutip jika jalur proyek Anda memiliki spasi di dalamnya.

Bill A.
sumber
Terima kasih atas saran itu, karena ini baru saja berhasil untuk saya di VS2012 juga.
Dib
2
Saya telah mengubah ini sedikit dalam kasus saya:xcopy /s /d /y "$(ProjectDir)\stuff" "$(TargetDir)\stuff"
Danny Staple
44

Karena saya tidak dapat mengomentari jawaban sebelumnya, saya akan memberikan solusinya di sini:

Menambahkan apa yang disediakan @PaulAlexander, tambahkan berikut ini ke file .csproj / .vbproj Anda:

<ItemGroup>
    <AvailableItemName Include="RootContent">
      <Visible>false</Visible>
    </AvailableItemName>  
</ItemGroup>
<Target Name="AfterBuild">
    <Copy
        DestinationFolder="$(OutputPath)"
        SourceFiles="@(RootContent)"
        SkipUnchangedFiles="true"
        />  
</Target>

Hal ini memungkinkan Anda untuk memilih "RootContent" sebagai Build Action di jendela Properties, dan semuanya dapat diakses melalui GUI. Penjelasan yang lebih lengkap: opsi "AvailableItemName" pada dasarnya membuat daftar bernama baru yang dapat Anda tetapkan untuk item dalam proyek di bawah properti "Build Action" di jendela Properties. Anda kemudian dapat menggunakan daftar yang baru dibuat ini di Target mana pun yang Anda suka (mis. Melalui "@ (RootContent)").

gelombang kejut
sumber
Jawaban bagus, gunakan saja ini sendiri untuk sukses!
Chris Marisic
Juga perhatikan bahwa VS 2010 (tidak yakin tentang versi yang lebih lama) akan mengeluh tentang AvailableItemNamemenjadi elemen yang tidak valid jika Anda mengedit file proyek dalam VS; abaikan saja peringatannya, tetap berfungsi.
Aaronaught
2
Sayangnya ini hanya menyalin file ke dalam direktori keluaran dari proyek yang file tersebut milik - dan bukan di direktori keluaran dari proyek startup. Ini penting saat menggunakan ini dalam proyek perpustakaan.
Sebastian Krysmanski
2
Ini berfungsi dengan baik untuk membangun dalam mode rilis dan debug dengan vs2008 tetapi tampaknya tidak berfungsi saat menggunakan penerbitan satu klik. Ada saran?
Soenhay
2
Tidak berhasil untuk saya di vs2015. Diperbaiki dengan menulis ulang target sedikit: <Target Name="RootOutputCopyTarget" AfterTargets="Build">... </Target>
lorond
44

Jika Anda mengedit .csproj / .vbproj di editor teks, Anda dapat mengontrol di mana file ditempatkan di direktori output, dan juga nama file yang akan ada di direktori output. Sebagai contoh:

<None Include="content\someContent.txt">
  <Link>someContentInOutputDirectory.txt</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

Ini akan memasukkan file content\someContent.txtke bin\someContentInOutputDirectory.txt. Anda juga dapat memilih subdirektori binjika Anda mau; cukup tambahkan ke elemen Link.

Daniel Yankowsky
sumber
3
Wow, beruntungkah saya membutuhkan ini sekarang dan bukan dua hari yang lalu. Terima kasih; ini bagus!
Asherah
2
Ya Tuhan, terima kasih. Saya hanya menghabiskan 6 jam mencoba untuk memperbaiki beberapa kasus sampah sudut di mana VS tidak menyalin .dll dengan cara yang cerdas. Ini adalah jawaban nyata untuk kehidupan, alam semesta, dan segalanya.
Brandon
5
Sejauh ini, ini adalah solusi terbaik
PhilHdt
1
Saya menemukan setelah saya melakukan ini dan memuat ulang proyek di studio visual, file ketergantungan menghilang dari penjelajah solusi seolah-olah tidak termasuk dalam proyek. Namun itu tetap membangun seperti yang diharapkan, dan menyalin ke keluaran seperti yang diinginkan. Sebagai solusi, saya sedang menambahkan setiap file dua kali; sekali tanpa tindakan, dan sekali dengan set 'salin ke keluaran'.
Éliette
1
Ini bukan tujuan penggunaan tag ini. Di VS2013, ini memunculkan peringatan saat memuat proyek, dan file tidak terlihat sebagai ditambahkan ke proyek karena itu adalah direktori proyek.
jpmc26
15

Saya percaya perintah XCOPY menangani direktori dan file dengan lebih baik. Karena itu,

    XCOPY "$(ProjectDir)common/browserhawk" "$(TargetDir)" /E /I /F /Y

Yang memungkinkan untuk membuat folder dari direktori target.

    XCOPY "$(ProjectDir)Templates" "$(TargetDir)" /E /I /F /Y

Struktur folder / file proyek dari:

    A:\TEMP\CONSOLEAPPLICATION3\TEMPLATES
    ├───NewFolder1
    ├───NewFolder2
    │       TextFile1.txt
    │       TextFile2.txt
    └───NewFolder3
            TextFile1.txt
            TextFile2.txt
            TextFile3.txt

Menjadi:

    A:\TEMP\CONSOLEAPPLICATION3\BIN\DEBUG
    │   ConsoleApplication3.exe
    │   ConsoleApplication3.pdb
    │   ConsoleApplication3.vshost.exe
    │   ConsoleApplication3.vshost.exe.manifest
    ├───NewFolder1
    ├───NewFolder2
    │       TextFile1.txt
    │       TextFile2.txt
    │
    └───NewFolder3
            TextFile1.txt
            TextFile2.txt
            TextFile3.txt
AMissico
sumber
/Dmungkin berguna juga, untuk menghindari menimpa kemungkinan perubahan.
KurzedMetal
10

Tambahkan berikut ini ke file .csproj / .vbproj Anda

<Target Name="AfterBuild">
    <Copy
        DestinationFolder="$(OutputPath)"
        SourceFiles="@(RootContent)"
        SkipUnchangedFiles="true"
        />  
</Target>

Kemudian ubah Build Action dari file apa pun yang Anda inginkan di folder root ke RootContent.

Paul Alexander
sumber
Tidak melalui dialog ... tetapi Anda dapat mengedit proyek Anda di VS. Klik kanan proyek dan pilih Unload Project. Kemudian klik kanan dan pilih Edit. Kemudian Anda dapat mengedit file MSBuild yang merupakan proyek Anda.
Paul Alexander
2
Terima kasih, ini terlihat berguna. Sayangnya, bahkan setelah menambahkan potongan Anda ke file .vbproj, RootContenttidak muncul dalam daftar tarik-turun "Build Action" dan memasukkannya secara manual menghasilkan kesalahan "Nilai properti tidak valid" dari Visual Studio. Apa yang saya lewatkan?
Heinzi
Tidak bekerja dengan proyek Aplikasi Konsol Visual Studio 2010 C #.
AMissico
Tidak bekerja dengan proyek Aplikasi Konsol Visual Studio 2010 VB.NET.
AMissico
Tidak bekerja dengan proyek Aplikasi Konsol Visual Studio 2008 C #.
AMissico
5

Saya telah menggunakan ini di VS2010, VS2015, VS2017, dan VS2019. Saya lebih suka solusi ini karena:

  1. XML dapat digunakan kembali dalam proyek apa pun
  2. "RootContent" dipilih sebagai Build Action di UI Visual Studio, sama seperti "Konten" lainnya
  3. "CopyToOutputDirectory" dipatuhi, seperti yang Anda harapkan
  4. RootContent ditambahkan ke keluaran proyek: dijalankan melalui Referensi-Proyek, mematuhi "Bersihkan", dll.
  5. RootContent dapat ditentukan dengan karakter pengganti, yang mempertahankan struktur folder rekursif:
<RootContent Include="common\browserhawk\**">
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</RootContent>

Menjelang awal file proyek:

  <ItemGroup>
    <AvailableItemName Include="RootContent">
      <!-- Add "RootContent" as a choice in the "Build Action" dropdown. -->
      <Visible>True</Visible>
    </AvailableItemName>
  </ItemGroup>

Dipinjam Dari Jawaban Ini

Setelah Impor Target Microsoft:

  <PropertyGroup>
    <AssignTargetPathsDependsOn>
      $(AssignTargetPathsDependsOn);
      IncludeRootContentAsContent;
    </AssignTargetPathsDependsOn>
  </PropertyGroup>
  <Target Name="IncludeRootContentAsContent">
    <CreateItem Include="@(RootContent)" AdditionalMetadata="TargetPath=%(RecursiveDir)%(Filename)%(Extension)">
      <Output ItemName="ContentWithTargetPath" TaskParameter="Include" />
    </CreateItem>
  </Target>

Dipinjam Dari Jawaban Ini

MattGerg
sumber
Ini bagus - saya akan menukar RootContentyang menyiratkan "kode keras" CustomContentuntuk menunjukkan ini adalah konten khusus yang kami tambahkan ke proyek ini dan kami perlu menyalinnya dengan cara khusus ini. Selain itu, saya perlu TargetPath=%(RecursiveDir)%(Filename)%(Extension)membuat ulang struktur folder dari CustomContentfile yang ditentukan ke jalur keluaran.
Jonno
@Jonno Tujuannya adalah untuk menyalin file langsung ke direktori output root, terlepas dari RecursiveDirectory. Build Action "Konten" bawaan sudah memberi kita mekanisme untuk menyalin sambil mempertahankan RecursiveDirectory.
MattGerg
Saya belum memiliki kesempatan untuk menguji ini untuk beberapa saat, tetapi bukankah pengaturan tindakan membangun "Konten" menyebabkan file di bawah /common/browserhawk/untuk disalin ke /bin/common/browserhawk/seperti yang dikatakan OP? IIRC, niat saya adalah untuk /common/browserhawk/a.txtberakhir /bin/a.txttetapi mengizinkan rekursi dari sana ke bawah, jadi /common/browserhawk/secret/stuff.pngberakhirlah /bin/secret/stuff.png.
Jonno
@ Jonno Ok, ya, itu masuk akal sekarang. Saya memperbarui jawaban untuk menyertakan %(RecursiveDirectory). Ini sangat keren, karena selain memilih file individual di IDE, Anda juga dapat menentukan beberapa file dengan wildcard. Saat menggunakan karakter **pengganti, seluruh struktur folder akan dipertahankan.
MattGerg
1
Terima kasih banyak atas jawaban yang luar biasa! Saya pikir jawaban ini adalah jawaban yang benar karena berikut ini: 1. Tidak ada cmds eksternal 2. platform silang
George Anisimov
2

Saya akhirnya menambahkan langkah ke file nant build untuk disalin setelah komplain berhasil

<target name="action.copy.browserhawk.config" depends="compile.source">
    <copy todir="${App.Web.dir}/bin/" includeemptydirs="false">
        <fileset basedir="${browserhawk.config.dir}">
            <include name="bhawk_bb.dat" />
            <include name="bhawk_sp.dat" />
            <include name="browserhawk.properties" />
            <include name="maindefs.bdd" />
            <include name="maindefs.bdf" />
            <include name="BH_PRO.lic" />
        </fileset>
    </copy>
    <echo message="COPY BROWSERHAWK CONFIG: SUCCESS   ${datetime::now()}" />
</target>
Steve Wright
sumber
2
+1 karena untuk seseorang yang menggunakan nant ini masih merupakan jawaban yang membantu
Chris Haines
1

Anda dapat membuat file batch untuk menyalin file dan menjalankannya sebagai peristiwa pasca-pembuatan.

jvanderh.dll
sumber
Saya akhirnya melakukan ini untuk salah satu proyek saya (meskipun saya menggunakan skrip Python daripada kelelawar).
Fire Lancer