C# Visual Studio:如何在不复制文件夹结构的情况下“复制到输出目录”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18743907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:04:58  来源:igfitidea点击:

Visual Studio: How to "Copy to Output Directory" without copying the folder structure?

c#visual-studio-2010

提问by OhDear

I have a few dll files in \lib folder of my project folder. In the property page of dll, I have selected "Build Action" as "Content" and "Copy to Output Directory" as "Copy always".

我的项目文件夹的 \lib 文件夹中有几个 dll 文件。在 dll 的属性页中,我选择了“构建操作”作为“内容”,将“复制到输出目录”选择为“始终复制”。

After build I am actually getting the dll copied but they are inside \bin\Release\lib and not in \bin\Release.

构建后,我实际上正在复制 dll,但它们在 \bin\Release\lib 中,而不是在 \bin\Release 中。

Is there a way to copy dll files to \bin\Release (and not to \bin\Release\lib) without writing a post-build script or resorting to nant etc?

有没有办法将 dll 文件复制到 \bin\Release(而不是 \bin\Release\lib)而无需编写构建后脚本或求助于 nant 等?

采纳答案by Daniel Zeitlin

instead of <Content>use <ContentWithTargetPath>and specify target path, like this:

而不是<Content>使用<ContentWithTargetPath>并指定目标路径,如下所示:

<ContentWithTargetPath Include="lib\some_file.dat">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  <TargetPath>some_file.dat</TargetPath>
</ContentWithTargetPath>

Note that this entry may not be visible from Visual Studio (2012, 2015, 2017), but once manually added to the csproj, it will appear in Visual Studio. The target path will not be editable through the UI though.

请注意,此条目可能在 Visual Studio(2012、2015、2017)中不可见,但一旦手动添加到 csproj,它将出现在 Visual Studio 中。但是,目标路径将无法通过 UI 进行编辑。

回答by Ani

Keep them in $(ProjectDir)\Lib, but add those files "As a link" to the root of your .csproj. Now they will get copied to bin\Debug (or whatever other output folder) without being in lib.

保留它们$(ProjectDir)\Lib,但将这些文件“作为链接”添加到 .csproj 的根目录。现在它们将被复制到 bin\Debug (或任何其他输出文件夹),而不是在 lib 中。

EDIT: This answer was written way back when ContentWithTargetPath was not available in the versions of VS/MSBuild I was using. Leaving this answer here for people who might have to use an older version of VS. Please stop commenting on this, we all know there are better ways now.

编辑:当 ContentWithTargetPath 在我使用的 VS/MSBuild 版本中不可用时,这个答案是写回来的。将这个答案留在这里给可能不得不使用旧版本 VS 的人。请停止对此发表评论,我们都知道现在有更好的方法。

回答by erik_nw

Add the dll-files as a reference to the project, and on the reference set "Copy local" to true.

添加 dll 文件作为对项目的引用,并在引用上将“复制本地”设置为 true。

回答by Petr Hendl

I had the same problem with Visual Studio 2010 / C# Project.

我在 Visual Studio 2010/C# 项目中遇到了同样的问题。

For assemblies (i. e. having the .NET interface) use folder "References" under your project in the Solution Explorer. Right click it, choose "Add existing item" and locate your .dll assembly.

对于程序集(即具有 .NET 接口),请使用解决方案资源管理器中项目下的文件夹“References”。右键单击它,选择“添加现有项目”并找到您的 .dll 程序集。

Common .dll files can be placed in a subfolder (as "\lib" was mentioned above) and in the properties select:

常见的 .dll 文件可以放在子文件夹中(如上面提到的“\lib”)并在属性中选择:

  • Build Action = "HelpFiles"
  • Copy To OutputDirectory = "If Newer"
  • 构建操作 =“帮助文件”
  • 复制到输出目录 = "如果更新"

This worked for me exactly as desired - during build, the .DLLs are copied to the output directory without the "\lib" subfolder.

这完全符合我的要求 - 在构建期间,.DLL 被复制到输出目录,而没有“\lib”子文件夹。

回答by DefenestrationDay

It seems in VisualStudio 2015 that if the dlls you are 'adding with a link' are in a subfolder of that same project- they will be automatically put a folder, and the output is also placed in a folder like you saw.

在 VisualStudio 2015 中,如果您“使用链接添加”的 dll位于同一个项目的子文件夹中- 它们将自动放置一个文件夹,并且输出也放置在您看到的文件夹中。

If the dlls are in another project or directory on disk not in a subfolder of the project, you can 'Add with a link', and they will be put in the root directory just fine.

如果 dll 在磁盘上的另一个项目或目录中,而不是在项目的子文件夹中,则可以“使用链接添加”,它们将被放置在根目录中就好了。

回答by sonny

If your main intent is to include DLLs without cluttering up the project root directory, another solution is to move the DLLs to a separate Shared Projectand add this as a reference in the original project.

如果您的主要目的是在不弄乱项目根目录的情况下包含 DLL,另一种解决方案是将 DLL 移动到单独的共享项目并将其添加为原始项目中的引用。

(Note that this post doesn't directly answer this question as it doesn't preserve the folder and project structure, but I found this approach useful because I was able to restructure my project in my case and because I wanted to avoid some of the downsides of the other approaches here.)

(请注意,这篇文章没有直接回答这个问题,因为它不保留文件夹和项目结构,但我发现这种方法很有用,因为我能够在我的情况下重组我的项目,并且因为我想避免一些此处其他方法的缺点。)

Steps

脚步

  • Right-click your Solution -> Add -> New Project -> Shared Project
  • Add the DLLs to this project (in the root directory of this project, not in a "lib" sub-folder)
  • (Check DLL file properties are set correctly, e.g. Build Action: Contentand Copy to Output Directory: Copy Always)
  • Right-click the original project's References -> Add Reference -> Shared Projects
  • Select the shared project you created earlier
  • 右键单击您的 Solution -> Add -> New Project -> Shared Project
  • 将 DLL 添加到此项目(在此项目的根目录中,而不是在“lib”子文件夹中)
  • (检查 DLL 文件属性设置是否正确,例如Build Action: ContentCopy to Output Directory: Copy Always
  • 右键单击原始项目的 References -> Add Reference -> Shared Projects
  • 选择之前创建的共享项目

The setup looks like this:

设置如下所示:

solution-explorer-screenshot

解决方案资源管理器截图

回答by dev-siberia

If you need to copy files from the Libs directory to the root folder VS2017:

如果需要将Libs目录下的文件复制到VS2017根文件夹:

<ItemGroup Condition="'$(Platform)' == 'x64'">
    <None Include="Libs\x64\**" Link="\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x86'">
    <None Include="Libs\x86\**" Link="\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

To any other folder, including Libs(RecursiveDir) folder

到任何其他文件夹,包括 Libs(RecursiveDir) 文件夹

<ItemGroup Condition="'$(Platform)' == 'x86'">
    <None Include="Libs\x86\**" Link="mycustomfolder\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

回答by ChuckEng

An alternate method is just to leave the items as type None. In the solution explorer, click on the ones you want to deploy and set the Contentproperty to True.

另一种方法是将项目保留为 type None。在解决方案资源管理器中,单击要部署的那些并将Content属性设置为True

Note: I did this in VS2019, and things can change from version to version.

注意:我在 VS2019 中这样做了,并且版本可能会有所不同。

To get this to work, now right-click on your project, and select "Unload Project". Then right-click on the unloaded project and select "Edit project_name.vcxproj".

要使其工作,现在右键单击您的项目,然后选择“卸载项目”。然后右键单击卸载的项目并选择“编辑 project_name.vcxproj”。

In the editor, go all the way to the bottom of the file and insert this target right right before the trailing </Project>tag:

在编辑器中,一直到文件底部,并在尾随</Project>标签之前插入此目标:

  <Target Name="CopyContent" AfterTargets="Build">
    <Copy SourceFiles="@(None)" Condition="'%(None.DeploymentContent)' == 'true'" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
  </Target>

Now right click on the unloaded project and select "Reload Project". Select to save and close if you are prompted.

现在右键单击卸载的项目并选择“重新加载项目”。如果出现提示,请选择保存并关闭。

I also set the OutputDirectoryto:

我还设置OutputDirectory为:

$(SolutionDir)bin\$(Configuration)\$(Platform)\

$(SolutionDir)bin\$(Configuration)\$(Platform)\

and the IntermediateDirectoryto:

IntermediateDirectory

$(SolutionDir)obj\$(Configuration)\$(ProjectName)\$(Platform)\

$(SolutionDir)obj\$(Configuration)\$(ProjectName)\$(Platform)\

in the Project Properties General page. This puts the output in a "bin" folder, and the intermediates in an "obj" folder in the root of your solution.

在“项目属性常规”页面中。这会将输出放在“bin”文件夹中,将中间体放在解决方案根目录中的“obj”文件夹中。

Note: The $(SolutionDir)is not defined when you run MSBuild from the command line. There is a trick you can use to define that to the folder where the .sln file lives using GetDirectoryNameOfFileAbove. (left as an exercise for the reader). Also, it looks like in 2019 they are handling this correctly on the command line anyway. Yeah :)The $(SolutionDir)contains a trailing backslash, hence none after it. The results of each must have a trailing backslash.

注意:$(SolutionDir)从命令行运行 MSBuild 时未定义。您可以使用一个技巧来使用 GetDirectoryNameOfFileAbove 将其定义到 .sln 文件所在的文件夹。(留给读者作为练习)。此外,看起来在 2019 年他们无论如何都在命令行上正确处理了这个问题。是啊:)$(SolutionDir)包含斜杠,后因此没有。每个的结果必须有一个尾随反斜杠。

Now, if you own Pro or above, please don't do this every time you need to create a project. That would be lame. Instead, once you have your project setup just the way you like it, select Project -> Export Template. You give it a name, and the next time you want to create a project just like that one, just choose that name in the New Project dialog. (In older version, I think this was Files -> Export Teamplate....)

现在,如果您拥有 Pro 或更高版本,请不要每次需要创建项目时都这样做。那会很蹩脚的。相反,一旦您按照自己喜欢的方式设置了项目,请选择Project -> Export Template。你给它一个名字,下次你想创建一个和那个一样的项目时,只需在“新建项目”对话框中选择该名称。(在旧版本中,我认为这是Files -> Export Teamplate....)