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


111

我的项目文件夹的\ lib文件夹中有一些dll文件。在dll的属性页中,我选择“生成操作”作为“内容”,选择“复制到输出目录”作为“总是复制”。

生成后,我实际上正在复制dll,但它们位于\ bin \ Release \ lib中,而不位于\ bin \ Release中。

有没有一种方法可以将dll文件复制到\ bin \ Release(而不是\ bin \ Release \ lib)而无需编写生成后脚本或诉诸nant等?

Answers:


255

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

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

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


2
在VS 2015中,我没有将ContentWithTargetPath视为“构建操作”选项。是否可以添加它?
2016年

1
将条目手动添加到.csproj文件后,它在IDE中显示为一个选项。但是,我仍然无法从IDE中编辑“目标路径”。
2016年

9
我唯一担心的是,由于VS2015 UI不显示此选项或TargetPath属性,因此将来的MSBuild / .NET / Visual Studio /任何版本都将不支持此功能。
MarioDS '16

1
这对我有用。没有其他答案对我有用。这应该是答案。
GunWanderer

1
注意,使用ContentWithTargetPath符渐进式编译(在2017年VS测试15.9.9)
的Mads Ravn的

26

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

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


4
谢谢ananthonline。我尝试了您的步骤,但没有帮助。可能是我做错了。这是我正在做的事情,如果您认为有问题,请更正:1.从项目中排除这些dll,但将它们放在lib中。2.右键单击项目,然后单击“添加现有项”。从库中选择dll,然后将它们“添加为链接”。3.右键单击dll,然后在“复制到输出目录”中再次选择“始终复制”。4.清理并重建。结果:我再次在\ bin \ release \ lib中获得了这些dll
OhDear 2013年

1
在配置解决方案文件夹后,请发布其屏幕截图
Ani

3
如果我尝试将链接添加到项目树中已经存在的文件,它将拒绝,而只是将文件再次包含到项目中...
Nyerguds

1
像@Nyerguds一样,我无法将链接添加到项目树中已存在的文件中,因此此答案不能解决问题。
ToreØstergaard

1
它不会淹没解决方案资源管理器中项目目录的根吗?对于许多这样的文件,这可能是一个问题。通常,项目目录的根目录已经包含各种文件。
Alex34758 '18

10

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

(请注意,本文并未直接回答此问题,因为它未保留文件夹和项目结构,但是我发现这种方法很有用,因为我能够根据自己的情况来重组项目,并且因为我想避免某些这里其他方法的缺点。)

脚步

  • 右键点击 Solution -> Add -> New Project -> Shared Project
  • 将DLL添加到该项目(在该项目的根目录中,而不是在“ lib”子文件夹中)
  • (检查DLL文件属性设置正确,如Build Action: ContentCopy to Output Directory: Copy Always
  • 右键单击原始项目的 References -> Add Reference -> Shared Projects
  • 选择您之前创建的共享项目

设置如下所示:

解决方案探索者的屏幕截图


2
到目前为止,简单而优雅的解决方案使项目保持整洁。
拉维·甘

我无法使其与UAP和* .bin文件一起使用。
Matteo

7

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


1
谢谢埃里克。除了一个我无法添加作为参考的dll之外,该方法非常有效。添加为引用时出现的错误是无法添加对'libeay32.dll'的引用。请确保该文件可访问,并且它是有效的程序集或COM组件。
OhDear 2013年

7
@MAnthony:只能将.NET程序集或COM互操作程序集添加为项目引用;本机DLL不能。您需要找到其他方法将DLL复制到\ bin \ Release。
Michael Liu

感谢Erik,Michael和ananthonline。抱歉,由于我没有所需的信誉度,因此无法对您的答案和评论进行投票。
OhDear 2013年

1
对于非托管DLL,您将需要使用以下建议的方法。
2013年

4

如果需要将文件从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>

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

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

3

似乎在Visual Studio 2015中,如果您要“添加链接”的dll 位于该项目的子文件夹中它们将自动放置在一个文件夹中,并且输出也将像您看到的那样放置在一个文件夹中。

如果dll位于项目的另一个目录或磁盘上的目录中,而不位于该项目的子文件夹中,则可以“添加链接”,它们将被放在根目录中。


与VS2012相同。它拒绝使它们成为链接,而只是将它们添加为内容。最后,可悲的是,最简单的解决方案似乎是将它们转储到项目根目录中。
Nyerguds '16

0

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

注意:我是在VS2019中执行此操作的,各个版本之间可能会发生变化。

为了使它起作用,现在右键单击您的项目,然后选择“卸载项目”。然后右键单击已卸载的项目,然后选择“编辑project_name.vcxproj”。

在编辑器中,一直移至文件底部,然后在尾随</Project>标记之前插入此目标:

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

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

我还将设置OutputDirectory为:

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

IntermediateDirectory到:

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

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

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

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


-1

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

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

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

  • 生成操作=“ HelpFiles”
  • 复制到OutputDirectory =“如果较新”

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

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.