如果在解决方案中使用项目依赖项,MSBuild 不会复制引用(DLL 文件) [英] MSBuild doesn't copy references (DLL files) if using project dependencies in solution

查看:20
本文介绍了如果在解决方案中使用项目依赖项,MSBuild 不会复制引用(DLL 文件)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Visual Studio 解决方案中有四个项目(每个项目都针对 .NET 3.5)——对于我的问题,只有这两个很重要:

I have four projects in my Visual Studio solution (everyone targeting .NET 3.5) - for my problem only these two are important:

  1. MyBaseProject <- 该类库引用了第三方 DLL 文件 (elmah.dll)
  2. MyWebProject1 <- 此 Web 应用程序项目引用了 MyBaseProject
  1. MyBaseProject <- this class library references a third-party DLL file (elmah.dll)
  2. MyWebProject1 <- this web application project has a reference to MyBaseProject

我在 Visual Studio 2008 中添加了对 MyBaseProject 的 elmah.dll 引用,方法是单击添加引用..."→浏览"选项卡 → 选择elmah.dll".

I added the elmah.dll reference to MyBaseProject in Visual studio 2008 by clicking "Add reference..." → "Browse" tab → selecting the "elmah.dll".

Elmah 参考的属性如下:

The Properties of the Elmah Reference are as follows:

  • 别名 - 全局
  • 复制本地 - 真实
  • 文化 -
  • 说明 - 用于 ASP.NET 的错误日志记录模块和处理程序 (ELMAH)
  • 文件类型 - 程序集
  • 路径 - D:websotherfolder\_myPath\__toolselmahElmah.dll
  • 已解决 - 正确
  • 运行时版本 - v2.0.50727
  • 指定版本 - 错误
  • 强名称 - 错误
  • 版本 - 1.0.11211.0

MyWebProject1 中,我通过以下方式添加了对 Project MyBaseProject 的引用:添加引用..."→项目"选项卡→选择MyBaseProject".此引用的属性相同,但以下成员除外:

In MyWebProject1 I added the reference to Project MyBaseProject by: "Add reference..." → "Projects" tab → selecting the "MyBaseProject". The Properties of this reference are the same except the following members:

  • 描述 -
  • 路径 - D:websCMSMyBaseProjectinDebugMyBaseProject.dll
  • 版本 - 1.0.0.0

如果我在 Visual Studio 中运行构建,elmah.dll 文件将与 MyBaseProject.dll 一起复制到我的 MyWebProject1 的 bin 目录!

If I run the build in Visual Studio the elmah.dll file is copied to my MyWebProject1's bin directory, along with MyBaseProject.dll!

但是,如果我为解决方案清理并运行 MSBuild(通过 D:websCMS> C:WINDOWSMicrosoft.NETFrameworkv3.5MSBuild.exe/t:ReBuild/p:Configuration=Debug MyProject.sln)elmah.dll 丢失在 MyWebProject1 的 bin 目录中 - 尽管构建本身不包含警告或错误!

However if I clean and run MSBuild for the solution (via D:websCMS> C:WINDOWSMicrosoft.NETFrameworkv3.5MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln) the elmah.dll is missing in MyWebProject1's bin directory - although the build itself contains no warning or errors!

我已经确保 MyBaseProject 的 .csproj 包含值为true"的 private 元素(这应该是 Visual 中copy local"的别名工作室):

I already made sure that the .csproj of MyBaseProject contains the private element with the value "true" (that should be an alias for "copy local" in Visual Studio):

<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..mypath\__toolselmahElmah.dll</HintPath>
    **<Private>true</Private>**
</Reference>

(默认情况下,私有标记没有出现在 .csproj 的 xml 中,尽管 Visual Studio 说复制本地"为真.我将复制本地"切换为假 - 保存 - 并再次将其设置为真 - 保存!)

(The private tag didn't appear in the .csproj's xml by default, although Visual Studio said "copy local" true. I switched "copy local" to false - saved - and set it back to true again - save!)

MSBuild 有什么问题?如何将 (elmah.dll) 引用复制到 MyWebProject1 的 bin?

我不想在每个项目的 postbuild 命令中添加 postbuild 复制操作!(想象一下我会有很多项目依赖于 MyBaseProject!)

I do NOT want to add a postbuild copy action to every project's postbuild command! (Imagine I would have many projects depend on MyBaseProject!)

推荐答案

我不知道为什么在 Visual Studio 和 MsBuild 之间构建时会有所不同,但这是我在 MsBuild 中遇到此问题时发现的和 Visual Studio.

I'm not sure why it is different when building between Visual Studio and MsBuild, but here is what I have found when I've encountered this problem in MsBuild and Visual Studio.

对于示例场景,假设我们有项目 X、程序集 A 和程序集 B.程序集 A 引用程序集 B,因此项目 X 包含对 A 和 B 的引用.此外,项目 X 包含引用程序集 A (例如 A.SomeFunction()).现在,您创建一个引用项目 X 的​​新项目 Y.

For a sample scenario let's say we have project X, assembly A, and assembly B. Assembly A references assembly B, so project X includes a reference to both A and B. Also, project X includes code that references assembly A (e.g. A.SomeFunction()). Now, you create a new project Y which references project X.

所以依赖链看起来像这样:Y => X => A => B

So the dependency chain looks like this: Y => X => A => B

Visual Studio/MSBuild 试图变得聪明,并且只将引用带入它检测到项目 X 需要的项目 Y;它这样做是为了避免项目 Y 中的引用污染.问题是,由于项目 X 实际上不包含任何显式使用程序集 B 的代码(例如 B.SomeFunction()),VS/MSBuild 没有检测到 B 是必需的通过 X,因此不会将其复制到项目 Y 的 bin 目录中;它只复制 X 和 A 程序集.

Visual Studio / MSBuild tries to be smart and only bring references over into project Y that it detects as being required by project X; it does this to avoid reference pollution in project Y. The problem is, since project X doesn't actually contain any code that explicitly uses assembly B (e.g. B.SomeFunction()), VS/MSBuild doesn't detect that B is required by X, and thus doesn't copy it over into project Y's bin directory; it only copies the X and A assemblies.

您有两种选择来解决这个问题,这两种方法都会导致程序集 B 被复制到项目 Y 的 bin 目录:

You have two options to solve this problem, both of which will result in assembly B being copied to project Y's bin directory:

  1. 在项目 Y 中添加对程序集 B 的引用.
  2. 向使用程序集 B 的项目 X 中的文件添加虚拟代码.

我个人更喜欢选项 2,原因有几个.

Personally I prefer option 2 for a couple reasons.

  1. 如果您将来添加另一个引用项目 X 的​​项目,您将不必记住还包含对程序集 B 的引用(就像您必须使用选项 1 那样).
  2. 您可以有明确的评论,说明为什么需要存在虚拟代码而不是删除它.因此,如果有人不小心删除了代码(比如使用查找未使用代码的重构工具),您可以很容易地从源代码管理中看到代码是必需的,并可以恢复它.如果您使用选项 1 并且有人使用重构工具来清理未使用的引用,则您没有任何评论;您只会看到从 .csproj 文件中删除了一个引用.

这是我遇到这种情况时通常添加的虚拟代码"示例.

Here is a sample of the "dummy code" that I typically add when I encounter this situation.

    // DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
    private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
    {
        // Assembly A is used by this file, and that assembly depends on assembly B,
        // but this project does not have any code that explicitly references assembly B. Therefore, when another project references
        // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
        // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
        // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
        var dummyType = typeof(B.SomeClass);
        Console.WriteLine(dummyType.FullName);
    }

这篇关于如果在解决方案中使用项目依赖项,MSBuild 不会复制引用(DLL 文件)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆