复制本地如何工作? log4net.dll 没有被复制到 MyProject 输出目录

Posted

技术标签:

【中文标题】复制本地如何工作? log4net.dll 没有被复制到 MyProject 输出目录【英文标题】:How does Copy-local work? log4net.dll is not being copied to MyProject output directory 【发布时间】:2010-09-24 03:11:52 【问题描述】:

我想知道引用的 copy-local=true 到底是做什么的。它是否将引用的程序集及其所有依赖项复制到输出目录?

我的情况如下: 我有一个使用 log4net 的自定义日志包装器。我构建了一个 MyLogWrapper.dll 的发布程序集,其中 log4net.dll 引用设置为 copy-local true。从 MyProject 引用 MyLogWrapper.dll 并将本地复制设置为 true 应该会导致 log4net.dll 也被复制,对吗?我只在 MyProject 中引用 MyLogWrapper.dll 而没有它的依赖项。 log4net.dll 没有被复制到 MyProject 输出目录,但 MyLogWrapper 的所有其他依赖项都是。可能是什么问题?

我做了更多的实验,似乎如果我从 GAC 中删除程序集 (log4net.dll),它就会开始在本地复制。谁能确认这是问题所在?

【问题讨论】:

【参考方案1】:

不幸的是,根据MSDN documentation 中的以下陈述,对于 GAC 中的程序集,CopyLocal 功能似乎无法正常工作。

如果您部署的应用程序包含对在 GAC 中注册的自定义组件的引用,则无论 CopyLocal 设置如何,该组件都不会随应用程序一起部署。在 Visual Studio 的早期版本中,您可以在引用上设置 CopyLocal 属性以确保部署程序集。现在,您必须手动将程序集添加到 \Bin 文件夹。这将审查所有自定义代码,降低发布您不熟悉的自定义代码的风险。

更多信息可以在以下页面中找到,该页面解释了有关项目引用如何工作的详细信息。

MSDN: Project References

【讨论】:

我在 DataDynamics ActiveReports for .NET 3.0 论坛上发表的帖子中添加了一个链接,该帖子涉及与使用活动报告部署的 dll 相关的相同问题。奇怪的是,我发现这种所谓的“设计”行为似乎取决于被引用的库,例如 WPFToolkit.dll 似乎复制到 bin 文件夹,无论它是否通过辅助引用。 datadynamics.com/forums/124306/ShowPost.aspx【参考方案2】:

在 MSDN here 上提出这个问题后 - 似乎这种行为是设计使然。 “如果您部署/复制包含对在 GAC 中注册的自定义组件的引用的应用程序,则无论 Copy Local 设置如何,该组件都不会随应用程序一起部署/复制。”

【讨论】:

VS 2015 对通过项目引用的间接引用进行了例外处理。例如 VS 2010 的行为并非如此。 connect.microsoft.com/VisualStudio/Feedback/Details/1804765【参考方案3】:

有一个技巧:将引用 Copy Local 设置为 false,然后再设置为 true,Visual Studio 会自动为该引用添加 Private 元数据。至少 VS 2010 可以。我最近这样做是为了解决我们的 TFS 构建服务器的一个问题,由于某种奇怪的原因,在 GAC 中安装了许多企业库组件,因此在从 TFS Drop 文件夹部署我们的项目时遇到了重大问题。那个假/真的把戏救了我们。

【讨论】:

这在我的机器上确实有效,但在我们的构建服务器上无效。似乎我无法删除我的赞成票。 如果它在新版本的VS上不起作用,那么,我想,我们别无选择,只能手动修改项目文件,将“复制本地”添加到项目XML文件中的引用中,然后稍后要非常小心,避免触及 Visual Studio 本身中的引用设置。但我将不得不对其进行更多调查,如果微软自 VS 2010 以来改变了 msbuild 的核心行为,那么即使是手动修复也可能不够......【参考方案4】:

您需要对本地复制有点警惕,因为它过去曾让我感到困惑!

只是偶尔,对于特定的 .dll,它会默默地无法将其复制到构建文件夹。通常这不会出现在开发机器上,因为 dll 通常也在 GAC 中(如果您安装了用于开发的开发工具/库),因此在分发/捆绑之前您不会注意到进入安装程序,并且客户端计算机上缺少所需的文件。

关于此错误的信息不多,但此线程针对特定库进行了演示:here。

已经被这个抓住了,我认为最好(通常在任何情况下)确切地知道您的项目需要哪些程序集并拥有一个脚本或类似的自动化操作来确保所有必需的组件都存在,无论是在什么时候您构建,或者更有可能在您制作安装程序或收集文件以进行分发时,

【讨论】:

您是否建议使用 vs 构建后事件来执行此操作? 我没用过,所以不能说是或否。在我的情况下,我有一个 NSIS 脚本,它为我正在编写的工具(一个可视化应用程序)生成安装程序。我不仅在安装程序中包含 *.dll,还对其进行了更新,以按名称包含每个程序集,以便在缺少任何程序集时收到警告。 ... 续。如果它丢失,它还会从其他地方获取正确的程序集,以便安装程序生成不会失败,但它警告说 VS 没有复制我需要的 .dll。【参考方案5】:

当 local copy 设置为 true 时,它​​会将属性 local copy = tue 的所有程序集复制到应用程序的 bin 目录中。

在您的情况下,dll 可能正在使用另一个 dll,因此它也需要。

【讨论】:

... GAC 中的除外。 如果项目被另一个项目引用到另一个项目输出目录,即使是 GAC 中的那些也会被 VS 2015 复制。看我的回答。【参考方案6】:

我发现,如果引用的项目依赖于 GAC 程序集,则在 Visual Studio 2015 中,项目引用不再尊重这一点。 GAC 程序集总是被复制到根项目输出中,并且 copy local = false 仅在项目的输出中包含对 GAC dll 的引用。

Connect feedback

【讨论】:

以上是关于复制本地如何工作? log4net.dll 没有被复制到 MyProject 输出目录的主要内容,如果未能解决你的问题,请参考以下文章

3rd 方库是指不同版本的 log4net.dll

如何使用 log4net 日志框架

C#Log4net记录日志(转)

WPF使用Log4net.dll库的demo(转载加个人观点)

在 WinForms 应用程序中引用 log4net DLL 的正确方法

(转)Log4Net 详解