150

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

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

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

4

11 回答 11

315

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

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

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

为该文件添加一个<None>条目将确保它仍显示在 Visual Studio 的 UI 中。

于 2016-01-28T15:20:03.530 回答
30

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

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

于 2013-09-11T14:40:07.770 回答
20

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

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

脚步

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

设置如下所示:

解决方案资源管理器截图

于 2019-06-04T18:53:15.210 回答
8

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

于 2013-09-11T15:05:33.920 回答
6

如果需要将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>
于 2019-06-23T16:43:39.233 回答
3

要将我的帽子添加到此处,如果您想要包含整个目录的内容并且您不想在 Visual Studio 中跟踪每个单独的文件,那么您可以将其添加到您的项目文件中(对我来说,这是一个.vcxproj文件UWP C++ 项目):

<ItemGroup>
    <Content Include="Content\**">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
</ItemGroup>

请注意,该Content目录必须与项目文件位于同一目录中,以保留目录结构。

于 2021-01-13T15:02:54.570 回答
3

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

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

于 2016-01-19T16:18:24.047 回答
1

上述解决方案对我来说在Visual Studio 2019 Professional v16.8.2. 有时文件会复制,有时不会。经过多次尝试,感觉在 VS 的最新更新中可能出现了问题。

这个答案显示了如何使用构建后脚本...... OP 要求不要做的事情!因此,此答案仅适用于那些(像我一样)无法使用更传统方法的人。

  • 右键单击项目并选择添加 > 现有项...
  • 导航到lib文件夹并选择要添加的项目
  • 在 的右侧Add,单击向下箭头并选择Add As Link
  • 右键单击项目中新“lib”文件夹中的每个文件,并将“复制到输出目录”设置为“不复制”
  • 打开项目属性Build Events并添加以下 Post-build 事件

,

rem Copy 3rd party DLL(s) to the output directory on successful build
COPY $(ProjectDir)lib\Something.dll $(TargetDir)
COPY $(ProjectDir)lib\SomethingElse.dll $(TargetDir)

请注意,您可以在构建后事件中使用通配符来复制多个文件。

于 2022-01-24T13:38:21.813 回答
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 或更高版本,请不要在每次需要创建项目时都这样做。那会很蹩脚。相反,一旦您按照自己喜欢的方式设置项目,请选择Project -> Export Template. 你给它一个名字,下次你想创建一个像那个一样的项目时,只需在“新建项目”对话框中选择该名称。(在旧版本中,我认为这是Files -> Export Teamplate....)

于 2019-07-18T23:19:26.113 回答
0

关于您的问题,以下步骤在Visual Studio 2019中对我有用:

在 Visual Studio 编辑器中,对于您的 dll,将“构建操作”设置设置为“内容”(这可能是可选的),将“复制到输出目录”设置为“不复制”

然后将在项目csproj文件中生成以下内容:

<ItemGroup>
  <Content Include="lib\IncludedDLL.dll" />
</ItemGroup>

改为将条目修改为以下内容:

<ItemGroup>
  <Content Include="lib\IncludedDLL.dll" />
  <Content Include="lib\IncludedDLL.dll">
    <Link>IncludedDLL.dll</Link>
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
</ItemGroup>

您可以将项目csproj文件中的"CopyToOutputDirectory"选项手动设置为"Always""PreserveNewest"

在 Visual Studio 编辑器中,它仍然会显示文件“复制到输出目录”设置为“不复制”,但文件在重建时复制到根输出目录。

如果您不想将文件复制到根输出目录,则不需要上述更改,因此,如果是这种情况,您可以手动删除项目 csproj 文件中的上述更改以恢复为非复制行为。

于 2021-02-22T09:52:21.680 回答
-1

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

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

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

  • 构建操作 =“帮助文件”
  • 复制到 OutputDirectory = "如果更新"

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

于 2015-03-17T14:19:47.097 回答