将.csproj中的内容文件包含在项目锥体之外

Pou*_*ulo 73 msbuild csproj

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

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

<Content Include="..\..\MyContentFiles\**">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Run Code Online (Sandbox Code Playgroud)

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

Man*_*ark 146

我相信@Dmytrii一方面是正确的 - 你想使用"链接"功能.

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

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

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

MSBuild知名项元数据页面详细介绍了您可以访问的元数据.

  • 我在荒野中遇到很少的食物和水,并且非常需要陪伴,我觉得这个答案很有帮助.通过遵循这些指示,我能够构建一个功能齐全的人工智能,现在已经取代了曾经在荒野中困扰过我的所有人类需求.谢谢Mandark! (7认同)
  • 不适用于 VS2017 (15.8.6) 上的 .NET Core 项目。 (3认同)
  • @Vijay 看到我的编辑,您需要`&lt;Content Include="..\..\MyContentFiles\**\*.*"&gt;` - 请注意路径末尾的`\*.*`。 (2认同)

Dmy*_*iak 45

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

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

但是你不能为目录树做这件事.
相反,你需要为此编写后期构建任务.这是一个让你盯着看的样本.

  • 如[此答案](http://stackoverflow.com/a/11808911/1576096)中所述,"您无法为目录树执行此操作".声明不正确. (7认同)

Rob*_*aap 27

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>
Run Code Online (Sandbox Code Playgroud)

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

<Import Project="include.proj" />
Run Code Online (Sandbox Code Playgroud)

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

在这里采取了这个技巧:http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx

  • 您可以将<Visible> true </ Visible>添加到Content元素,以使项目显示在Solution Explorer中. (6认同)
  • 不适用于VS2017(15.8.6)上的.NET Core项目. (2认同)

Tod*_*odd 10

您将添加到项目文件底部的以下内容将复制内容文件,将后构建事件中的目录结构维护到构建的目标目录$(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>
Run Code Online (Sandbox Code Playgroud)

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

<MakeDir Directories="$(TargetDir)\MyContentFiles" Condition=" !Exists('$(TargetDir\MyContentFiles') " />
Run Code Online (Sandbox Code Playgroud)

并改变

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

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


zwc*_*oud 10

要将文件包含在 .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>
Run Code Online (Sandbox Code Playgroud)

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


小智 5

我认为

<Content Include="..\..\MyContentFiles\**\*.*">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Run Code Online (Sandbox Code Playgroud)

就足够了,因为您想要该文件夹和子文件夹中的所有内容