【问题标题】:Assembly in GAC is not copied to output in project that references a project that references the GAC assembly with CopyLocal=trueGAC 中的程序集未复制到项目中的输出,该项目引用了一个项目,该项目引用了具有 CopyLocal=true 的 GAC 程序集
【发布时间】:2011-11-24 11:48:49
【问题描述】:

我有一个“项目 A”,它使用 CopyLocal=TRue 引用 System.Web.Mvc。 System.Web.Mvc 在我的本地机器和构建服务器上都在 GAC 中。

我还有一个“项目 B”,它在“项目 B”的输出中引用了“项目 A”,而 System.Web.Mvc 在构建期间没有被复制到。

我怀疑这是因为它在 GAC 中。 这是真的? 我可以做些什么让 MSBuild 将其复制到输出文件夹吗?

我在此线程中阅读了 Muse VsExtensions 的答案,其中仅讨论了对 GAC 的直接引用,但是我们通过“项目 A”进行了间接引用: .NET Reference "Copy Local" True / False Being Set Based on Contents of GAC

这篇博文也相关: http://deeperdesign.wordpress.com/2010/02/08/msbuild-assembly-dependencies-and-the-gac/

【问题讨论】:

  • 有趣的是,即使您的项目引用了不在 GAC 中的程序集副本,这似乎也会发生。 VS 发现 GAC 中存在副本,因此不会复制它。
  • 假设是正确的。将 MSBuild 详细程度设置为诊断会在解析依赖项时提供 This reference is not "CopyLocal" because it's registered in the GAC.

标签: msbuild gac msbuild-projectreference


【解决方案1】:

您是否检查了 .csproj 文件以验证该引用确实包含 <Private>True</Private> 标记?不幸的是,复制本地在 xml 中有 3 种状态 - True、False 和...缺失。

【讨论】:

  • 我实际上将 True 添加到“项目 B”的 csproj 文件中,它引用了“项目 A”。但我仍然没有在输出文件夹中得到 System.Web.Mvc。
  • 在“项目 A”中,我已经在 csproj 文件中有 True
  • True 对这个问题没有帮助。
  • 谢谢。这确实解决了我的问题。我有一个 Azure Worker Role 项目,其中打包的部署文件缺少一些引用的 DLL。由于其他原因,这些 DLL 在我的本地计算机上的 GAC 中(但不会在 Azure 上的 GAC 中)。即使项目引用具有 Copy Local,在记事本中打开项目文件显示每个 DLL 都缺少私有标记。我将 Copy Local 属性更改为 false,保存项目,然后返回 true 并再次保存。这足以让缺失的私有标签插入到 .csproj 项目文件 xml 中并正确插入 Azure。
【解决方案2】:

一个务实的(阅读技巧)解决方案是我在“项目 B”中引用了 System.Web.Mvc.dll。 这绝对不是正确的解决方案,所以请给我一个更好的解决方案:-)

【讨论】:

  • 接受我的投票。这就是我多年来处理这种垃圾的方式。
  • 嗨 khebbie,你找到解决办法了吗?
  • 这比标记为答案的解决方案更好
【解决方案3】:

我看到的一个建议是,将所有项目更改为具有相同的输出路径。不过,这价值有限,因为如果您有一个依赖链,例如: 项目 B > 项目 A > 库 C 那么这可能是因为 Prj A 在多个应用程序之间共享,您希望每个应用程序都有自己的输出路径。

我通过改用 MSBuild 编译并在每个构建上设置 OutDir 属性解决了这个问题。

例如MSBuild projectB.csproj /p:OutDir=C:\AppBOutput\

这会将项目 B、其依赖项目 (prj A) 和 prj As 的输出复制本地依赖项全部到 C:\AppBOutput\ 目录中。

为什么会起作用

在 Visual Studio 中构建项目时,prj A 和 prj B 都有自己的输出目录,例如prjA\bin\debugprjB\bin\debug。 GAC 存储的程序集设置为 copylocal 将包含在直接引用它的项目的输出目录中 (prjA)。但它将不会复制到引用该项目 (prjB) 的项目的输出目录。这就是项目引用复制的工作方式。深入研究 MSBuild 目标,我确信可以找到根本原因(抱歉,不是我自己做的)。

/p:OutDir=C:\AppBOutput\ MSBuild 参数的作用是将所有项目的输出目录设置为相同。通过这样做,您可以避开 MSBuild 如何复制项目到项目的参考输出的行为。无需依赖 MSBuild 将prjA\bin\debug 中的一些 内容复制到prjB\bin\debug,您只需强制所有项目输出到同一目录即可。

【讨论】:

  • 目前尚不清楚这将如何解决问题。在这种情况下,将所有项目设置为输出到同一目录绝对没有任何作用
  • 自从@Al-Muhandis 发表评论以来,我收到了一些对此答案的反对意见,因此我编辑了我的答案以解释 为什么 这有效。我现在还用 VS2015 和 MSBuild 14.0 重新测试了该解决方案 4 年半! 并且可以验证它仍然以相同的方式运行。鉴于现在最好通过 NuGet 引用 MVC,这一点在这方面有点悬而未决,但对于其他 GAC ed 程序集来说情况仍然相同,例如System.Xml.dll。
猜你喜欢
  • 2016-01-13
  • 1970-01-01
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
  • 1970-01-01
相关资源
最近更新 更多