【问题标题】:Copy files to output directory using csproj dotnetcore使用 csproj dotnetcore 将文件复制到输出目录
【发布时间】:2017-11-06 12:43:05
【问题描述】:

所以我的问题很简单。我有一些文件想要复制到构建输出目录,无论是调试构建还是发布发布。我能找到的所有信息都是关于旧的 json 配置方法。有人有使用 dotnetcore 的 csproj 的示例吗?

【问题讨论】:

    标签: c# .net-core


    【解决方案1】:

    有很多方法可以实现您的目标,具体取决于您的需求。

    最简单的方法是有条件地设置元数据 (CopyToOutputDirectory / CopyToPublishDirectory) 项目(假设 .txtNone 项目而不是 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>
    

    这会将文件复制到相应的目录。有关&lt;Copy&gt; 任务的更多选项,请参阅its documentation。要将其限制为某些配置,您可以使用Condition 属性:

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

    Condition 属性既可以应用于&lt;Target&gt; 元素,也可以应用于&lt;Copy&gt; 等任务元素。

    【讨论】:

    • 我将如何将“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>
    

    【讨论】:

    • 所有其他答案/建议的所有其他排列都对我不起作用。甚至没有在详细的构建输出中提及该文件。但你的建议在这里奏效了。
    • 如果你想包含中间子文件夹,请使用&lt;Content Include="layouts\**\*.*"&gt;
    • 使用 Web SDK (&lt;Project Sdk="Microsoft.NET.Sdk.Web"&gt;) 时,它不允许您使用 Include=,因为它似乎已经在 SDK 中隐式指定了。我必须使用 Update= 来构建并包含我的其他文件。
    • 很好,谢谢.. 但是如何仅将文件夹的内容复制到输出目录而不是文件夹本身。表达式assets\*.* 应该假设它。但它会复制完整的资产文件夹。所以我有bin/Debug/netcoreapp3.1/assets/... 但我希望资产文件夹的文件到输出的根目录。 bin/Debug/netcoreapp3.1/....
    • 我找到了解决方案:xml &lt;Project Sdk="Microsoft.NET.Sdk"&gt; &lt;ItemGroup&gt; &lt;AssetsSourceFiles Include="assets/**/*.*"/&gt; &lt;/ItemGroup&gt; &lt;Target Name="CopyCustomContent" AfterTargets="AfterBuild"&gt; &lt;Copy SourceFiles="@(AssetsSourceFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" /&gt; &lt;/Target&gt; &lt;/Project&gt; (请参阅我的答案以获得更好的代码格式。)
    【解决方案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>
          

          【讨论】:

          • 理想情况下使用 任务使其跨平台。
          猜你喜欢
          • 1970-01-01
          • 2017-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-06
          • 2017-03-10
          相关资源
          最近更新 更多