Salin file ke direktori keluaran menggunakan csproj dotnetcore


109

Jadi masalah saya cukup sederhana. Saya memiliki beberapa file yang ingin saya salin ke direktori build output apakah itu build debug atau rilis terbitkan. Semua informasi yang dapat saya temukan adalah tentang pendekatan konfigurasi json lama. Adakah yang punya contoh menggunakan csproj dengan dotnetcore?

Jawaban:


148

Ada beberapa cara untuk mencapai tujuan Anda, tergantung pada kebutuhan Anda.

Pendekatan termudah adalah menyetel item metadata ( CopyToOutputDirectory/ CopyToPublishDirectory) secara bersyarat (dengan asumsi .txtsebagai Noneitem, bukan Content, jika tidak berhasil, coba <Content>saja):

<ItemGroup Condition="'$(Configuration)' == 'Debug'">
  <None Update="foo.txt" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

Jika lebih banyak kontrol diperlukan, pendekatan yang paling serbaguna adalah menambahkan target kustom yang terhubung ke proses build di file csproj:

<Target Name="CopyCustomContent" AfterTargets="AfterBuild">
  <Copy SourceFiles="foo.txt" DestinationFolder="$(OutDir)" />
</Target>
<Target Name="CopyCustomContentOnPublish" AfterTargets="Publish">
  <Copy SourceFiles="foo.txt" DestinationFolder="$(PublishDir)" />
</Target>

Ini menyalin file ke direktori masing-masing. Untuk opsi lebih lanjut untuk <Copy>tugas tersebut, lihat dokumentasinya . Untuk membatasinya ke konfigurasi tertentu, Anda dapat menggunakan Conditionatribut:

<TargetCondition=" '$(Configuration)' == 'Release' ">

ConditionAtribut ini dapat diterapkan baik pada <Target>elemen atau elemen tugas seperti <Copy>.


Bagaimana saya menerapkan 'DestinationFolder' ke item <Referensi>, atau mungkinkah, tidak banyak di dokumen yang dapat saya temukan. Saya tidak ingin semua rakitan saya berada di tingkat root dan lebih suka mereka berada di folder mereka sendiri.
Reahreic

Anda dapat mengatur DestinationSubDirectory="subdir\"metadata pada Referenceitem secara langsung. Namun ini berarti Anda perlu mengimplementasikan resolusi perakitan sendiri ( acara AssemblyResolve )
Martin Ullrich

Bagaimana cara menyalin folder induk yang berisi beberapa dll di masing-masing folder. Saya ingin membuatnya tersedia di jalur keluaran yang diterbitkan sehingga setelah membangun folder ini r tersedia untuk aplikasi saya saat dijalankan, saat saya memuat dll ini sebagai plugin saat startup. Saya menggunakan rider di mac
kuldeep

97

Meskipun ini membantu saya menyelesaikan masalah saya, ini tidak berfungsi untuk semua file di sub-direktori. Saya juga menggunakan Content Includedaripada Content Update.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="layouts\*.*">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>  
  </ItemGroup>

</Project>

3
Setiap permutasi lain dari semua jawaban / saran lainnya gagal untuk saya. Bahkan tidak menyebutkan file dalam output build verbose. Tetapi saran Anda di sini berhasil.
pengguna7817808

15
Dan jika Anda ingin menyertakan penggunaan subfolder perantara<Content Include="layouts\**\*.*">
JSancho

3
Saat menggunakan Web SDK ( <Project Sdk="Microsoft.NET.Sdk.Web">), Anda tidak dapat menggunakannya Include=karena tampaknya secara implisit menentukannya dalam SDK. Saya harus menggunakannya Update=untuk membangun dan menyertakan file tambahan saya.
notracs

Bagus, terima kasih .. Tetapi cara menyalin hanya konten folder ke direktori output, bukan folder itu sendiri. Ekspresi assets\*.*harus mengasumsikannya. Tapi itu menyalin folder aset lengkap. Jadi saya punya bin/Debug/netcoreapp3.1/assets/...Tapi saya ingin file-file dari folder aset ke direktori root dari output. bin/Debug/netcoreapp3.1/....
Dominik

Saya menemukan solusi: xml <Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <AssetsSourceFiles Include="assets/**/*.*"/> </ItemGroup> <Target Name="CopyCustomContent" AfterTargets="AfterBuild"> <Copy SourceFiles="@(AssetsSourceFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" /> </Target> </Project> (lihat jawaban saya untuk format kode yang lebih baik.)
Dominik

15

Dengan asumsi Anda memiliki assetsfolder di direktori root Anda. Anda dapat menamainya sesuai keinginan. Ini hanya sebuah contoh:

proyek-Anda.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <AssetsSourceFiles Include="assets/**/*.*"/>
  </ItemGroup>

  <Target Name="CopyCustomContent" AfterTargets="AfterBuild">
    <Copy SourceFiles="@(AssetsSourceFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
  </Target>
</Project>

ini hanya menyalin konten assetsfolder ke root keluaran tanpa membungkusnya ke dalam assetsfolder. Tetapi jika Anda ingin menyalin dengan folder itu sendiri, Anda dapat menggunakan kode berikut:

<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <Content Include="assets\**\*.*">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
</Project>

15

Tempatkan ini di file .csproj Anda, ganti nlog.config dengan jalur file yang diinginkan. Kemudian simpan dan buat proyek Anda:

<ItemGroup>
  <Content Update="Nlog.config">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
</ItemGroup>

Tampaknya ini tidak menyalin subdirektori.
nol

3

Saya memiliki persyaratan untuk pilihan template HTML agar dapat digunakan di sisi klien dan sisi server (Handlebars js)

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Content Update="wwwroot\html-templates\**\*.*">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

</Project>

0
<PropertyGroup>
    <PostBuildEvent>xcopy "$(ProjectDir)Xml" "$(ProjectDir)$(OutDir)Xml" /S /F /I /R /Y</PostBuildEvent>
</PropertyGroup>

atau

<PropertyGroup>
    <PostBuildEvent>copy /Y "$(ProjectDir)MyXml.xml" "$(ProjectDir)$(OutDir)Xml"</PostBuildEvent>
</PropertyGroup>

1
Idealnya gunakan tugas <Copy> untuk membuatnya lintas platform.
Bruno Garcia

0

Jika Anda perlu memaksa salinan paket NuGet tertentu ke dalam proyek ASP.NET Core (2.2), tambahkan di akhir csproj Anda:

<!-- Force copy MathNet because we need it in compilation -->
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="Build">
    <PropertyGroup>
        <ErrorText>This project references NuGet package(s) that are missing on this computer. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\MathNet.Numerics.4.8.1\lib\netstandard2.0\MathNet.Numerics.dll')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MathNet.Numerics.4.8.1\lib\netstandard2.0\MathNet.Numerics.dll'))" />
</Target>

<ItemGroup>
    <ContentWithTargetPath Include="..\packages\MathNet.Numerics.4.8.1\lib\netstandard2.0\MathNet.Numerics.dll">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       <TargetPath>MathNet.Numerics.dll</TargetPath>
    </ContentWithTargetPath>
</ItemGroup>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.