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

发布于 2024-08-01 16:40:35 字数 444 浏览 5 评论 0原文

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

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

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

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

I have a C# project say MyProject.csproj located at "C:\Projects\MyProject\". I also have files that I want copied into the output directory of this project. But, the files are at the location "C:\MyContentFiles\", i.e. they are NOT within the project cone. This directory has sub-directories as well. The contents of the directory is not managed. Hence I have to include all what is under it.

When I include them as 'Content' in the project, they are copied, but the directory structure is lost. I did something like this:-

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

How do I copy these files/directories recursively into the output directory of the project with the directory structure preserved?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

单身狗的梦 2024-08-08 16:40:35

您将添加到项目文件底部的以下内容将在构建后事件中将维护目录结构的内容文件复制到构建的目标目录 $(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" />

The following, which you would add to the bottom of your project file, will copy your content files maintaining the directory structure in a after build event to the target directory $(TargetDirectory) of your build (typically $(MSBuildProjectDirectory)\bin\Debug ).

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

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

If these files needed to go in a directory named MyContentFiles, you could add this before the copy:

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

and change

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

To

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />
呆橘 2024-08-08 16:40:35

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

The answer of Mandark adds the content files directly to the solution, and they will show up in the solution explorer. Whenever a file is added or deleted in the original directory, this is not picked up by visual studio automatically. Also, whenever a file is deleted or added in the solution explorer, the project file is altered, and all files are included separately, instead of just including the folder.

To prevent this, you can use the same trick, but put it in a separate project file and then import it.

The project file (for example include.proj) looks like this:

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

In your own project file, add the following line

<Import Project="include.proj" />

Visual Studio will not mess with this file, and just adds files as content during a build. Changes in the original directory are always included. The files won't show up in your solution explorer, but will be included in the output directory.

Picked up on this trick here: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx

软甜啾 2024-08-08 16:40:35

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

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

但是您不能对目录树执行此操作。
相反,您需要为此编写构建后任务。 这是一个让您感兴趣的示例

You need to add file as a link:

  1. Right click on the project in VS.
  2. Add -> Existing Item...
  3. Find the file.
  4. Select it and.
  5. Add as a Link (drop down in the Add Button in the dialog).
  6. Open the properties of the file and set "Copy to Output Directory" to "Copy always".

BUT You cannot do it for the directory tree.
Instead you need to write post-build task for that. This is a sample that will get you stared.

猫弦 2024-08-08 16:40:35

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

然而,当他说不能链接到目录树时,他只说对了一部分。
虽然在尝试使用 Visual Studio 的 GUI 添加链接时确实如此,但 MSBuild 支持这一点。

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

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

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

I believe @Dmytrii gets it right on one hand - you want to use the "link" feature.

However, he's only partly correct when saying you can't link to a directory tree.
While this is, indeed, true when trying to add the links using Visual Studio's GUI, MSBuild supports this.

If you want to preserve the directory structure, just add the %(RecursiveDir) tag to your <link> node:

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

The page MSBuild Well-known Item Metadata goes into more detail on the metadata you can access.

缺⑴份安定 2024-08-08 16:40:35

要将文件包含在 .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>

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

To include files in a folder for a .NET Core project,

<!--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>

And the items' property "Copy to Output Directory" will be "Copy if newer":
Copy if newer

花开半夏魅人心 2024-08-08 16:40:35

我认为

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

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

I think

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

Is just enough, since you want everything in that folder and subfolders

东北女汉子 2024-08-08 16:40:35

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

<ItemGroup>
 <Content Include="appsettings.local.json">
   <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory>
 </Content>
</ItemGroup>

To ignore a file in a .Net Core project:

<ItemGroup>
 <Content Include="appsettings.local.json">
   <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory>
 </Content>
</ItemGroup>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文