在 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 完全相同,但主应用程序项目没有复制copy
d .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 您应该在<Content>
中添加<Link>%(Filename)%(Extension)</Link>
以避免创建整个目录结构并且只复制文件。
根据MSDN,您可以添加可选属性Visible=true
以在解决方案资源管理器中显示内容。例如<Content Visible="true" Include="..."
另外,<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
只会在更新版本而不是每个版本时复制。【参考方案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
的 xcopyxcopy "$(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 文件复制到发布版本中的发布目录中?