Скопіюйте файли у вихідний каталог за допомогою csproj dotnetcore


103

Тож моє питання досить просте. У мене є кілька файлів, які я хочу скопіювати до каталогу виводу збірки, будь то збірка налагодження або публікація у випуску. Вся інформація, яку я можу знайти, стосується старого підходу до налаштування json. Хто-небудь мав приклад використання csproj із dotnetcore?

Відповіді:


143

Існує досить багато способів досягти своїх цілей, залежно від ваших потреб.

Найпростіший підхід - це умовне встановлення метаданих ( CopyToOutputDirectory/ CopyToPublishDirectory) елементів (припускаючи, .txtщо це Noneелемент, а не Content, якщо це не працює, спробуйте <Content>замість цього):

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

Якщо потрібно більше контролю, найбільш універсальним підходом є додавання власних цілей, які підключаються до процесу збірки у файлі 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>

Це копіює файл у відповідні каталоги. Додаткові параметри <Copy>завдання див. У його документації . Щоб обмежити це певними конфігураціями, ви можете використовувати Conditionатрибут:

<Target … Condition=" '$(Configuration)' == 'Release' ">

Цей Conditionатрибут може застосовуватися як до <Target>елемента, так і до елементів завдання, наприклад <Copy>.


Як би я застосував 'DestinationFolder' до елементів <Reference>, чи це можливо, у документах я не можу знайти багато чого. Я не хочу, щоб усі мої збірки були на кореневому рівні, і я б волів, щоб вони були у власній папці.
Reahreic

Ви можете встановити DestinationSubDirectory="subdir\"метадані для Referenceелементів безпосередньо. Однак це означає, що вам потрібно впровадити резолюцію зборів самостійно ( подія AssemblyResolve )
Мартін Улліх,

Як я можу скопіювати батьківську папку, яка містить деякі dll у відповідних папках. Я хочу зробити їх доступними у вихідному опублікованому шляху, щоб після побудови цих папок було доступно для мого додатка під час виконання, оскільки я завантажую ці dll як плагіни під час запуску. Я використовую rider на mac
kuldeep

93

Хоча це допомогло мені відсортувати свою проблему, вона не спрацювала для всіх файлів у підкаталозі. Я також використовував, Content Includeа не 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
Будь-яка інша перестановка всіх інших відповідей / пропозицій не спрацювала для мене. Навіть не згадка про файл у детальному виведенні збірки. Але ваша пропозиція тут спрацювала.
користувач7817808

15
А якщо ви хочете включити проміжні вкладені папки, використовуйте<Content Include="layouts\**\*.*">
JSancho

3
При використанні веб-SDK ( <Project Sdk="Microsoft.NET.Sdk.Web">) це не дозволяє вам використовувати, Include=оскільки це, схоже, вже неявно вказує, що всередині SDK. Мені довелося використати Update=його, щоб побудувати та включити мої додаткові файли.
notracs

Приємно, дякую .. Але як скопіювати лише вміст папки у вихідний каталог, а не саму папку. Вираз assets\*.*повинен це припускати. Але він копіює повну папку активів. Отже, у мене є, bin/Debug/netcoreapp3.1/assets/...але я хочу, щоб файли папки "активи" знаходились у кореневому каталозі вихідних даних. bin/Debug/netcoreapp3.1/....
Домінік

Я знайшов рішення: 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> (див. Мою відповідь для кращого формату коду.)
Домінік

15

Помістіть це у свій файл .csproj, замінивши nlog.config на потрібний шлях до файлу. Тоді просто збережіть його та створіть свій проект:

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

Здається, це не копіює підкаталоги.
нуль

13

Припускаючи, що у вас є assetsпапка у вашому кореневому каталозі. Ви можете назвати його як завгодно. Це лише приклад:

your-project.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>

це копіює лише вміст assetsпапки у вихідний корінь, не переносячи його в assetsпапку. Але якщо ви хочете скопіювати з самою папкою, ви можете використовувати такий код:

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

3

У мене була вимога до вибору шаблонів HTML, які можна використовувати як на стороні клієнта, так і на стороні сервера (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

Дякуємо, ви економите мій день, якщо вам потрібно примусово скопіювати певний пакет nuget до основного проекту asp.net (2.2), додайте в кінці вашого csproj:

<!-- 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>

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

або

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

1
В ідеалі використовуйте завдання <Copy>, щоб зробити його крос-платформенним.
Бруно Гарсія,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.