如何使Visual Studio将DLL文件复制到输出目录?

Mat*_*Mat 94 dll visual-studio visual-c++

我有一个依赖外部DLL文件的Visual Studio C++项目.在构建项目时,如何使Visual Studio自动将此DLL文件复制到输出目录(调试/发布)?

Adr*_*son 87

在项目中使用构建后操作,并添加命令以复制有问题的DLL.后构建操作是作为批处理脚本编写的.

输出目录可以引用为$(OutDir).项目目录可用$(ProjDir).尝试在适用的情况下使用相对路径,以便您可以复制或移动项目文件夹,而不会破坏构建后操作.

  • 如果链接中断:"xcopy/y"$(ProjectDir)*.dll""$(OutDir)" (35认同)
  • 值得指出的是,他可以通过项目>属性>构建事件>构建后事件来设置构建后事件. (24认同)
  • 样品:HTTP://eyeung003.blogspot.com/2009/11/visual-studio-post-build-event-to-copy.html (20认同)
  • 将/ d标志添加到xCopy以防止不必要地重新复制输出目录中未更改的文件. (8认同)
  • `$(TargetDir)` 而不是 `$(OutDir)` (2认同)

小智 38

$(OutDir)原来是VS2013中的一个相对路径,所以我不得不将它与$(ProjectDir)结合起来以达到预期的效果:

xcopy /y /d  "$(ProjectDir)External\*.dll" "$(ProjectDir)$(OutDir)"
Run Code Online (Sandbox Code Playgroud)

顺便说一句,您可以通过在开头添加"echo"来轻松调试脚本,并在构建输出窗口中观察扩展文本.

  • $(TargetDir)可以替换$(ProjectDir)$(OutDir),因为它还是两者的组合。 (2认同)
  • 如果源文件较旧或与现有文件相同,则添加 /d 可防止覆盖。如果目标被另一个进程锁定,则可能发生访问被拒绝错误。 (2认同)

Dar*_*ryl 19

要使用 GUI 执行此操作,首先将文件添加到项目中:右键单击项目,选择“添加...”,然后选择“现有项目”,然后浏览到要添加的一个或多个文件,然后单击“添加”。接下来,告诉 Visual Studio 在构建时复制文件:右键单击要复制的文件,选择“属性”。您将看到属性列表,包括“项目类型”。将“项目类型”更改为“复制文件”。点击“确定”即可完成。

这是文件属性对话框:

文件属性对话框

查看 *.vcxproj 文件,上面的步骤添加如下内容:

<ItemGroup>
    <CopyFileToFolders Include="libs\a.dll" />
    <CopyFileToFolders Include="libs\a.dll" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

我找不到 <CopyFileToFolders> 的任何官方文档,但显然它是受支持的,否则 GUI 不会使用它。但是,如果您手动执行此操作,并且未记录的项目类型让您感到不舒服,您始终可以使用众所周知但稍微详细的 <Content> 类型:

<ItemGroup>
    <Content Include="libs\a.dll" >
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="libs\b.dll" >
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案。这是正确的方法,因为 DLL 包含在解决方案文件列表中,因此您可以知道它们是否丢失。它将允许您根据配置和平台复制不同的DLL,并且不需要手动编辑项目文件,也不需要依赖外部命令进行复制。 (3认同)
  • 同意这一点应该被接受。此外,“项目类型”对于所有配置文件都是全局的,而不是针对每个配置文件。要以不同方式对待 x86 与 x64 配置文件(例如),“从构建中排除”字段_是_每个特定配置文件,并且按您的预期工作。 (2认同)

Seb*_*ian 7

当尝试将输出dll从一个C++项目复制到同一解决方案中另一个C#项目的发布和调试文件夹时,上面的注释部分中的详细信息对我(VS 2013)不起作用.

我必须添加以下post build-action(右键单击具有.dll输出的项目)然后属性 - >配置属性 - >构建事件 - >构建后事件 - >命令行

现在我添加了这两行来将输出dll复制到两个文件夹中:

xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Release
xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Debug
Run Code Online (Sandbox Code Playgroud)


Mar*_*ata 5

(此答案仅适用于 C# 不适用于 C++,抱歉我误读了原始问题)

我以前也经历过这样的 DLL 地狱。我的最终解决方案是将非托管 DLL 作为二进制资源存储在托管 DLL 中,并在程序启动时将它们提取到一个临时文件夹中,并在处理时将其删除。

应该是 .NET 或 pinvoke 基础结构的一部分,因为它非常有用......它使您的托管 DLL 易于管理,无论是使用 Xcopy 还是作为更大的 Visual Studio 解决方案中的项目引用。完成此操作后,您不必担心构建后事件。

更新:

我在另一个答案中发布了代码/sf/answers/772686351/

  • 我同意,它应该是框架的一部分(用于静态链接 dll 等)——值得注意的是,将 dll 作为资源存储然后在运行时提取它可能会在某些公司环境中导致问题(特别是如果他们有主动防病毒软件)。 (3认同)

Joh*_*n_J 5

project.csproj文件中添加内置 COPY :

  <Project>
    ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Debug\bin" SkipUnchangedFiles="false" />
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Release\bin" SkipUnchangedFiles="false" />
    </Target>
  </Project>
Run Code Online (Sandbox Code Playgroud)