在Visual Studio中复制DLL的依赖项


67

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

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

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


创建一个复制DLL的构建后事件,您无需为此创建项目。
奥塔维奥·德西奥

1
这种方法使我可以将主应用程序的实际依赖项与类库的依赖项分开。不幸的是,没有一种自动的方法(在主应用程序中不会引入伪引用)。
M. Dudley

Answers:


41

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

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

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

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

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

如果您点击“ edit post build ...”按钮,它将弹出一个框,其中列出了您可以插入的这些预定义变量(如$(SolutionDir)$(TargetDir)

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


6
副本中是否可以包含通配符,例如副本SOME_DIRECTORY * .dll $(TargetDir)?
dumbledad

我有与OP完全相同的方案,但是主应用程序项目未复制copyd .dll文件。
布兰登2014年

1
报价是什么?这仅在删除引号(VS2017)时对我有用。
Jeppe

25

以下片段对我有用:

<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中尝试过。


2
这就是我复制单个文件的方式。dllname.dll是文件,而不是文件夹
sergtk

3
这会将整个目录结构复制到bin中。像bin \ Path \ to \ dll \ dllname.dll他想拥有bin \ dllname.dll
Radu Simionescu

3
您应该添加<Link>%(Filename)%(Extension)</Link>内部内容<Content>以避免创建整个目录结构,而仅复制文件。
Martin Valgur

1
根据MSDN,您可以添加一个可选属性Visible=true以在“解决方案资源管理器”中显示内容。例如<Content Visible="true" Include="..."
ergohack,

2
此外,<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>仅在较新的版本(而不是每个版本)上才复制。
ergohack

6

看看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,保存,设置copy-local = True,保存。

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


1
该帖子不再提供文件
Noctis 2014年


2

我不建议这样做。最终,要复制的程序集数量(如果有可能正在重建)爆炸了N ^ 2。如果可能,应该将所有项目的程序集都放在同一$(OutDir)中。如果您使用的是TFS,Team Build会为您完成。


3
实际上,我们确实将所有程序集都放在一个目录中。我的主要应用程序在那里引用了它们,并且在我构建它时将它们自动从该目录复制到bin / Debug。我还希望复制依赖项的依赖项。
M. Dudley

2

转到主应用程序参考,即您的类库参考。

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

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


4
这会将第3方库复制到类库的bin目录中,但不复制到最终输出目录中
Michael Blackburn

2

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

我的构建事件如下所示:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

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

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


0

如果只想在构建后复制新文件,则还可以将xcopy/ i / d / y标志一起使用

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

-3

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>

-4

除了在项目本身中添加对所说的.dll的引用之外,我真的不知道有什么方法可以这样做。我们在这里的一些自己的项目中已经遇到了这个问题,我们发现的唯一解决方案是添加参考。我想说的是,我们的一位开发人员进行了一些研究,发现这是唯一的解决方案,但请不要在此引用我。


2
我们发现执行预构建或后构建任务是完成此任务的唯一方法。
krystan荣誉
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.