在项目锥之外包括.csproj中的内容文件


85

我有一个C#项目,说MyProject.csproj位于“ C:\ Projects \ MyProject \”。我也有一些文件要复制到该项目的输出目录中。但是,文件位于“ C:\ MyContentFiles \”位置,即它们不在项目区域内。该目录也包含子目录。目录的内容不受管理。因此,我必须包括其下的所有内容。

当我将它们作为“内容”包含在项目中时,它们会被复制,但是目录结构会丢失。我做了这样的事情:

<Content Include="..\..\MyContentFiles\**">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

如何在保留目录结构的情况下将这些文件/目录递归复制到项目的输出目录中?

Answers:


55

您需要添加文件作为链接:

  1. 在VS中右键单击该项目。
  2. 添加->现有项目...
  3. 查找文件。
  4. 选择它并。
  5. 添加为链接(在对话框的“添加”按钮中下拉)。
  6. 打开文件的属性,然后将“复制到输出目录”设置为“始终复制”。

但是您不能为目录树执行此操作。
相反,您需要为此编写后构建任务。这是一个样本,可以让您凝视。


8
该答案中所述,“您不能为目录树执行此操作”。陈述不正确。
曼达克

160

我相信@Dmytrii一方面可以解决问题-您想使用“链接”功能。

但是,在说您无法链接到目录树时,他只是部分正确。的确,当尝试使用Visual Studio的GUI添加链接时,确实如此,但MSBuild支持这一点。

如果要保留目录结构,只需将%(RecursiveDir)标签添加到您的<link>节点即可:

<Content Include="..\..\MyContentFiles\**\*.*">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

MSBuild著名项目元数据页面将详细介绍您可以访问的元数据。


1
1)如果从共享资产存储中删除文件会发生什么?看起来它不会从解决方案目录中删除2)有什么方法可以让Visual Studio在运行完成后从$(SolutionDir)中删除这些文件。将它们留在那里可能会使其他开发人员感到困惑。
亚当

@亚当,请参阅下面的答案
罗宾·范德纳普

8
我因缺少食物,水而在旷野坠毁,并且非常需要陪伴,我发现此答案很有帮助。通过遵循这些说明,我得以构建出功能全面的AI,该AI现在已取代了曾经在这里的旷野困扰我的所有人类需求。谢谢曼达克!
deepelement 2014年

1
@Vijay看到我的编辑,您需要<Content Include="..\..\MyContentFiles\**\*.*">-注意\*.*路径的末尾。
CAD bloke

2
不适用于VS2017(15.8.6)上的.NET Core项目。
zwcloud

29

Mandark的答案将内容文件直接添加到解决方案中,它们将显示在解决方案资源管理器中。每当在原始目录中添加或删除文件时,Visual Studio都不会自动选择该文件。此外,无论何时在解决方案资源管理器中删除或添加文件,项目文件都会被更改,并且所有文件都单独包含在内,而不仅仅是包含文件夹。

为避免这种情况,您可以使用相同的技巧,但将其放在单独的项目文件中,然后将其导入。

项目文件(例如include.proj)如下所示:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="..\..\MyContentFiles\**">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

在您自己的项目文件中,添加以下行

<Import Project="include.proj" />

Visual Studio不会弄乱此文件,而只会在构建过程中将文件作为内容添加。始终包含原始目录中的更改。这些文件不会显示在您的解决方案资源管理器中,但是将包含在输出目录中。

在此处选择此技巧:http : //blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx


1
出于某种原因,使用.proj文件似乎对我来说不起作用,但是我能够使其与.csproj文件一起工作。
StriplingWarrior 2014年

6
您可以将<Visible> true </ Visible>添加到Content元素,以使这些项目出现在解决方案资源管理器中。
Michael Baker

我只用一个.proj就可以了
Jason Dufair

这对我根本不起作用,我认为这是因为要链接的项目本身是在预构建事件中生成的。
Paul K

2
不适用于VS2017(15.8.6)上的.NET Core项目。
zwcloud

10

以下内容(您将添加到项目文件底部的内容)会将维护了after build事件中目录结构的内容文件复制到构建的目标目录$(TargetDirectory)(通常为$(MSBuildProjectDirectory)\bin\Debug)。

<ItemGroup>
    <ExtraContent Include="$(MSBuildProjectDirectory)\..\..\MyContentFiles\**" />
</ItemGroup>

<Target Name="AfterBuild">
    <Copy 
        SourceFiles="@(ExtraContent)" 
        DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" 
        SkipUnchangedFiles="true" />
</Target>

如果这些文件需要放在名为MyContentFiles的目录中,则可以在复制之前添加以下文件:

<MakeDir Directories="$(TargetDir)\MyContentFiles" Condition=" !Exists('$(TargetDir\MyContentFiles') " />

并改变

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />

1
您的转换类型为o:@(ExtraContent)->'...')应该为@(ExtraContext->'...')。否则很好的答案!
alexdej 2010年

@Todd 1)如果从MyContentFiles存储中删除文件会发生什么?看起来它不会从解决方案目录中删除2)有什么方法可以让Visual Studio在运行完成后从$(SolutionDir)中删除这些文件。将它们留在那里可能会使其他开发人员感到困惑。
亚当

3

我认为

<Content Include="..\..\MyContentFiles\**\*.*">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

就足够了,因为您希望所有内容都在该文件夹和子文件夹中


2

要将文件包含在.NET Core项目的文件夹中,

<!--Just files-->
<ItemGroup>
  <None Update="..\..\MyContentFiles\**\*.*">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>
<!--Content files-->
<ItemGroup>
  <Content Include="..\..\MyContentFiles\**\*.*" Link="MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

项目的属性“复制到输出目录”将是“如果更新则复制”:
如果较新则复制


-1

要忽略.Net Core项目中的文件:

<ItemGroup>
 <Content Include="appsettings.local.json">
   <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory>
 </Content>
</ItemGroup>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.