在 Visual Studio 中复制 DLL 的依赖项

Posted

技术标签:

【中文标题】在 Visual Studio 中复制 DLL 的依赖项【英文标题】:Copying a DLL's dependencies in Visual Studio 【发布时间】:2010-11-05 20:19:24 【问题描述】:

如何在 Visual Studio 中设置项目以复制项目引用之一所依赖的第三方 DLL?

我有一个主应用程序项目和一个类库 DLL。主应用程序引用了类库DLL,而DLL本身又引用了一些第三方DLL。当我编译主应用程序时,它会自动将类库 DLL 复制到其输出目录,但不会复制第三方 DLL。

我不想从主应用程序项目中添加对第三方 DLL 的引用,因为主应用程序不使用它们,它们仅由类库使用。

【问题讨论】:

创建一个复制 DLL 的构建后事件,您无需为此创建项目。 此方法允许我将主应用程序的实际依赖项与类库的依赖项分开。太糟糕了,没有自动方式(不会在主应用程序中引入伪引用)。 【参考方案1】:

您可以通过项目属性窗口来实现这一点。 Visual Studio 允许您定义要在构建之前、构建之前或之后发生的事件。要进入项目属性窗口,只需在解决方案资源管理器窗口中右键单击您的项目,然后单击“属性”。从左侧转到“构建事件”选项卡。

在构建后的框中键入一些复制命令。例如:

copy "$(SolutionDir)mydll.dll" "$(TargetDir)"

其中$(SolutionDir)$(TargetDir) 都是预定义变量。标准语法如下:

copy "source directory and file name" "destination directory"

如果您单击“编辑构建后...”按钮,它将弹出一个框,其中列出了您可以插入的这些预定义变量(例如 $(SolutionDir)$(TargetDir)

附带说明,这是复制其他文件的有用过程,例如自定义配置文件、图像或您的项目可能具有的任何其他依赖项。

【讨论】:

副本能否包含通配符,如副本 SOME_DIRECTORY*.dll $(TargetDir)? 我的场景与 OP 完全相同,但主应用程序项目没有复制 copyd .dll 文件。 引号是干什么用的?这仅在删除引号时对我有用(VS2017)。【参考方案2】:

以下片段对我有用:

<Project>
  ...
  <ItemGroup>
    <Content Include="Path\to\dll\dllname.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  ...
</Project>

这适用于 C#。 对于原生 C++,它仍然将 dll 复制到输出文件夹,但此依赖在 Visual Studio 中不可见,应直接在项目文件中编辑。

测试不平凡的例子 我试图运行依赖于原生 C++ 项目 B 的 C# 项目 A。B 项目依赖于第三方原生 dll C——这种依赖是通过上面的项目文件中的片段实现的。 当我构建 A 时,C 被复制到二进制文件夹中。

我在 Visual Studio 2010 中尝试过。

【讨论】:

这就是我复制 single 文件的方式。 dllname.dll 是文件,而不是文件夹 这会将整个目录结构复制到 bin。比如 bin\Path\to\dll\dllname.dll 他想要 bin\dllname.dll 您应该在&lt;Content&gt; 中添加&lt;Link&gt;%(Filename)%(Extension)&lt;/Link&gt; 以避免创建整个目录结构并且只复制文件。 根据MSDN,您可以添加可选属性Visible=true 以在解决方案资源管理器中显示内容。例如&lt;Content Visible="true" Include="..." 另外,&lt;CopyToOutputDirectory&gt;PreserveNewest&lt;/CopyToOutputDirectory&gt; 只会在更新版本而不是每个版本时复制。【参考方案3】:

看看 Alex Yakunin 提供的这个解决方案 http://blog.alexyakunin.com/2009/09/making-msbuild-visual-studio-to.html 它对我的工作非常好 - 明确使用 DevExpress 库的场景有其他依赖项,这些依赖项在部署时会导致问题)

注 1:Visual Studio 2010 似乎会自动添加引用的 dll,但 msbuild 没有。因此,自从发布脚本使用 msbuild 后,Alex 的解决方案就奏效了。 注意 2:还必须确保对于引用的库(在代码中引用的库),在 csproj 中将 copy-local 实际上设置为 True,即使解决方案资源管理器说是。最好的方法是设置 copy-local = False, Save, set copy-local = True, Save。

这两个步骤 - 引用库的 copy-local=true 和为间接引用添加 msbuild 目标自动为我构建设置。

【讨论】:

该帖子上的文件不再可用 页面现在是404。请参阅:web.archive.org/web/20180521114840/http://blog.alexyakunin.com/…【参考方案4】:

我不希望我的依赖文件位于项目根文件夹中,而是位于子文件夹中。但文件必须放在 build 文件夹的根文件夹中。

我的构建事件如下所示:

 Command: call xcopy /S /Y "$(SolutionDir)Dependencies\*.*" "$(TargetDir)"

如果“依赖项”也包含子文件夹,就像我的一样。

/S 也表示复制子文件夹 /Y 表示不提示覆盖确认

其他xcopy参数可以在:https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/xcopy

【讨论】:

【参考方案5】:

我不建议这样做。您最终会导致被复制(并且可能正在重建)的程序集数量激增 N^2。如果可能,您应该让所有项目将它们的程序集放在同一个 $(OutDir) 中。如果您使用的是 TFS,Team Build 会为您执行此操作。

【讨论】:

实际上,我们确实将所有程序集放在一个目录中。我的主应用程序在那里引用它们,当我构建它时,它们会自动从该目录复制到 bin/Debug。我想要一种方法来复制依赖项的依赖项。【参考方案6】:

转到主应用程序、引用、类库引用。

将“复制本地”设置为 True。

它现在会将您的类库的 bin 目录复制到主应用程序的 bin 目录中。包括任何子依赖的第三方 dll。

【讨论】:

这会将第三方库复制到类库的bin目录中,但不会复制到最终输出目录中【参考方案7】:

如果您只想在构建后复制新文件,您还可以使用带有标志 /i /d /y

xcopy
xcopy "$(ProjectDir)SubDir\*.dll" "$(TargetDir)" /i /d /y

【讨论】:

【参考方案8】:

100% 确定这会起作用。 只需将 dll 替换为您的个人参考。文件

<Reference Include="Xceed.Wpf.Toolkit">
  <HintPath>..\..\..\3rdParty\Extended WPF Toolkit-2.2.1\Xceed.Wpf.Toolkit.dll</HintPath>
   <CopyToOutputDirectory>Always</CopyToOutputDirectory>   
   <SpecificVersion>False</SpecificVersion> 
</Reference>

<Content Include="..\..\..\3rdParty\Extended WPF Toolkit-2.2.1\Xceed.Wpf.Toolkit.dll">
  <Link>Xceed.Wpf.Toolkit.dll</Link>
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  <SpecificVersion>False</SpecificVersion>
</Content>

【讨论】:

【参考方案9】:

除了在项目本身中添加对上述 .dll 的引用之外,我真的不知道有什么方法可以做到这一点。我们在这里的一些自己的项目中遇到过这个问题,我们找到的唯一解决方案是添加引用。我想说我们的一位开发人员做了一些研究,发现这是唯一的解决方案,但不要引用我的话。

【讨论】:

我们发现执行构建前或构建后任务是完成此任务的唯一方法。

以上是关于在 Visual Studio 中复制 DLL 的依赖项的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio:将依赖的 DLL 复制到目标文件夹

从属 DLL 未复制到 Visual Studio 中的生成输出文件夹

Visual Studio 2010 DTE:如何使添加的 DLL 引用成为绝对引用而不是复制

如何设置 Visual Studio 以将所需的 DLL 文件复制到发布版本中的发布目录中?

Visual Studio 发布未将所有 DLL 复制到发布文件夹

使用 Visual Studio 2015、C++ 项目的 DLL 没有“复制到输出目录”