使用 csproj dotnetcore 将文件复制到输出目录
Posted
技术标签:
【中文标题】使用 csproj dotnetcore 将文件复制到输出目录【英文标题】:Copy files to output directory using csproj dotnetcore 【发布时间】:2017-11-06 12:43:05 【问题描述】:所以我的问题很简单。我有一些文件想要复制到构建输出目录,无论是调试构建还是发布发布。我能找到的所有信息都是关于旧的 json 配置方法。有人有使用 dotnetcore 的 csproj 的示例吗?
【问题讨论】:
【参考方案1】:有很多方法可以实现您的目标,具体取决于您的需求。
最简单的方法是有条件地设置元数据 (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>
任务的更多选项,请参阅its documentation。要将其限制为某些配置,您可以使用Condition
属性:
<Target … Condition=" '$(Configuration)' == 'Release' ">
此Condition
属性既可以应用于<Target>
元素,也可以应用于<Copy>
等任务元素。
【讨论】:
我将如何将“DestinationFolder”应用于Reference
项目上设置DestinationSubDirectory="subdir\"
元数据。但是,这意味着您需要自己实现程序集解析 (AssemblyResolve event)
如何复制包含相应文件夹中一些 dll 的父文件夹。我想让它们在输出发布路径中可用,以便在构建这些文件夹 r 在运行时可用于我的应用程序之后,因为我在启动时将这些 dll 作为插件加载。我在 mac 上使用 Rider
警告,如果您使用的是 Azure Pipelines,并且要复制的文件不存在,除非来自同一 .csproj
文件中的 PreBuild 步骤。您将遇到构建代理“错过”文件的先有鸡还是先有蛋的问题。这可能与他们在构建步骤中提供的警告有关:docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/…【参考方案2】:
虽然这有助于我解决问题,但它不适用于子目录中的所有文件。我还使用了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>
【讨论】:
所有其他答案/建议的所有其他排列都对我不起作用。甚至没有在详细的构建输出中提及该文件。但你的建议在这里奏效了。 如果你想包含中间子文件夹,请使用<Content Include="layouts\**\*.*">
使用 Web SDK (<Project Sdk="Microsoft.NET.Sdk.Web">
) 时,它不允许您使用 Include=
,因为它似乎已经在 SDK 中隐式指定了。我必须使用 Update=
来构建并包含我的其他文件。
很好,谢谢.. 但是如何仅将文件夹的内容复制到输出目录而不是文件夹本身。表达式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>
(请参阅我的答案以获得更好的代码格式。)【参考方案3】:
假设您的根目录中有一个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>
【讨论】:
太好了,我错过了 assets**. ... 用于指定深度的两个通配符。谢谢!【参考方案4】:将它放在您的 .csproj 文件中,将 nlog.config 替换为所需的文件路径。然后只需保存它并构建您的项目:
<ItemGroup>
<Content Update="Nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
【讨论】:
这似乎不会复制子目录。【参考方案5】:我需要选择一些 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>
【讨论】:
【参考方案6】:例如,您有一个名为 test.txt 的文件。要将始终复制设置为此文件,您需要将此部分添加到您的 .csproj 文件中:
<ItemGroup>
<None Include="test.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
【讨论】:
【参考方案7】:如果您需要将特定 NuGet 包强制复制到 ASP.NET Core 项目 (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>
【讨论】:
【参考方案8】:<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>
【讨论】:
理想情况下使用以上是关于使用 csproj dotnetcore 将文件复制到输出目录的主要内容,如果未能解决你的问题,请参考以下文章
相当于 dotnet core/csproj 中的 AssemblyInfo