在.csproj中包含项目外的内容文件

问题描述:

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

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

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

如何递归地复制这些文件/目录与目录结构的项目的输出目录保存?

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

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

但是你不能这样做的目录树。
相反,您需要为此编写后期构建任务。 This is a sample这会让你盯上。

+5

正如[这个答案](HTTP陈述://stackoverflow.com/a/11808911/1576096),“你不能为目录树做它。”声明不真实。 – Mandark 2013-06-13 13:00:49

以下内容将添加到项目文件的底部,它会将维护目标结构的内容文件复制到构建目标目录$(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-10-06 04:27:42

+0

@Todd 1)如果从MyContentFiles存储中删除文件,会发生什么情况?它看起来不像将从解决方案目录中删除2)是否有任何方法让Visual Studio在运行完成后从$(SolutionDir)中删除这些文件。离开他们可能会混淆其他开发者。 – Adam 2013-11-21 12:08:13

我相信@Dmytrii一方面可以正确使用 - 您想使用“链接”功能。

但是,他说只有部分正确的时候说你不能链接到一个目录树。 当尝试使用Visual Studio的GUI添加链接时确实如此,MSBuild支持这一点。

如果你想保留目录结构,只是%(RecursiveDir)标签添加到您的<link>节点:

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

MSBuild Well-known Item Metadata进入您可以访问元数据的详细信息。

+1

1)如果从Shared Assets存储中删除文件,会发生什么情况?它看起来不像将从解决方案目录中删除2)是否有任何方法让Visual Studio在运行完成后从$(SolutionDir)中删除这些文件。离开他们可能会混淆其他开发者。 – Adam 2013-11-21 12:07:36

+0

@亚当看到我的回答如下 – 2014-10-05 22:58:02

+4

由于食物,水和亟需陪伴的旷野在荒野中坠毁,我觉得这个答案很有帮助。按照这些指示,我能够建立一个全功能的AI,现在已经取代了曾经在荒野中萦绕在我身边的所有人类需求。谢谢Mandark! – deepelement 2014-12-16 17:45:32

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-10-29 18:59:16

+5

您可以将 true添加到Content元素以使项目出现在解决方案资源管理器中。 – 2015-01-14 23:41:21

+0

Mine只是一个.proj – 2016-02-05 19:58:02

我觉得

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

仅仅是不够的,因为你想要的文件夹中的一切都和子文件夹