【问题标题】:how do I work around log4net keeping changing publickeytoken我如何解决 log4net 不断变化的 publickeytoken
【发布时间】:2012-02-03 08:46:07
【问题描述】:

我们有一个 asp.net 4.0 项目,它使用了几个依赖于 log4net 版本 1.2.10.0 的框架。今天我尝试包含一个依赖于 log4net 版本 1.2.11.0 的新框架,从那以后我一直被卡住:

log4net 1.2.10.0 有 publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 有 publickeytoken = 669e0ddf0bb1aa2a

由于这些不同,我不能通过 web.config 中的运行时元素使用程序集重定向(让所有框架使用相同版本的 log4net)或代码库(让新框架使用版本 1.2.11.0)。

我在这里有什么选择?

(以及为什么 log4net 会在版本之间不断更改 publickeytokens,据我所知,丢失的密钥是在版本 1.2.9.0 和 1.2.10.0 之间切换的原因,他们是否又丢失了密钥?我会如果他们需要,请自愿为我的保管箱保管它...)

编辑:好的,所以 log4net 的人显然认为使用两个键发布是个好主意,但这意味着您使用的 每个 框架都需要就 他们喜欢的两种风格,或者这些框架不能在同一个应用程序域中并行工作。只有我一个人觉得这是个可怕的主意吗?如果每个人都这样做,那么一切都会崩溃,对吧?

Edit2:正如我所说,我没有在我的业务代码中使用 log4net,但我使用了几个依赖于 1.2.10.0 的框架,当我尝试使用依赖于 1.2.11.0 的新框架时出现了问题(新密钥),所以 Stefans 的回答不适用,因为新框架会期望新密钥,而不是旧密钥

【问题讨论】:

  • 恕我直言,这里 apache 的第一个错误是提供使用新密钥签名的二进制文件:新密钥用于修补/增强的开源版本,不应按原样使用。第二个错误是您所说的框架已发布,仅带有新的 log4net 签名:应该存在带有旧签名的版本。
  • 实际上,您看到的是第三种风格:SAP 的天才们以他们自己的强名重新编译,作为 Crystal Reports for Visual Studio 包的一部分,更糟糕的是,他们将其卡在 GAC 中,这将使您跨机器的依赖关系成为一场噩梦。

标签: .net dll log4net publickeytoken


【解决方案1】:

这就是我使用 1.2.11.0 版本的方式。

  1. 首先诅咒 apache 更改密钥 :)
  2. Download 使用旧密钥签名的 1.2.11.0 版本。
  3. 通过删除对 log4net 的任何直接引用(新密钥)并替换为对使用旧密钥签名的程序集的引用来整理您自己的代码。
  4. 通过在您的 web/app.config 中包含此段来整理您可能拥有的任何依赖程序集
   <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-1.2.10.0"
                                 newVersion="1.2.11.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>

【讨论】:

  • 下载使用旧公钥签名的版本是必要的,因为不幸的是,无法使用不同的公钥执行绑定重定向到程序集。
  • 这似乎因 1.2.11.0 中的重大更改而失败:netpl.blogspot.com/2012/03/…
  • 有没有人找到解决@sydneyos 提到的链接中描述的问题的解决方案,导致以下异常:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
  • 不幸的是,除了降级到 1.2.10 之外,没有其他解决方案。 (或重新编译您使用的每个依赖程序集)。
  • 将 1.2.10 程序集放在不同的目录中并使用此配置:''
【解决方案2】:

我正在使用通过 nuget 下载的最新版本的 log4net。但是,我正在使用的库之一需要旧版本。我的烦恼让我想到了这个问题。

其他答案的问题是它们对所有绑定都使用相同的 dll 版本。我想将新版本中的功能用于除遗留依赖项之外的所有其他内容。

要做到这一点,您需要执行以下操作:

  1. downloading旧版本(1.2.11.0版本)开始。
  2. 将下载的二进制文件重命名为log4net.1.2.10.dll。将其包含在您的启动项目中,并将 Build action 设置为 None 和“如果较新则复制”
  3. 告诉 .NET 在哪里可以找到旧版本:

App.config

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
            <codeBase version="1.2.10.0" href="log4net.1.2.10.dll" />
        </dependentAssembly>
    </assemblyBinding>
</runtime>

href 属性标识旧版本的位置。因此,对 log4net 的所有其他请求都将指向新版本。

【讨论】:

  • 这是一个很好的解决方案,因为它允许您为引用其中任何一个的库维护两个版本。
  • 谢谢!这救了我。我不得不将“复制到输出目录”更改为“不复制”,否则它就像一个魅力!
【解决方案3】:

您可以下载使用旧密钥签名的 log4net 1.2.11.0 版本。他们的常见问题解答中解释了更改为新密钥的原因:

http://logging.apache.org/log4net/release/faq.html#two-snks

(基本上新密钥是公开可用的,出于某种原因,他们不想在分发中包含旧密钥。我不清楚他们为什么不只是公开旧密钥)

【讨论】:

  • 但是当我使用绑定到新密钥的第三方库时,我仍然卡住了(对吗?)。使用新的 log4net 不是 我的 选择,它是第三方框架。随着越来越多的框架开始使用带有新密钥的 log4net,我不明白这些东西不会在每个人的脸上爆炸
  • 不幸的是,这是正确的。我想您需要考虑不要让所有组件都使用相同版本的 log4net...
  • .... 我该怎么做呢? .net 中是否有任何机制来处理此问题?
【解决方案4】:

不知道它是否适合您的特定情况,但您可以重新编译其中一个框架,因此它们将使用具有相同公钥的 log4net。就我而言,它是 FluentNHibernate,它使用 log4net 1.2.10 和 Combres 与 log4net 1.2.11 和新密钥。我下载了用旧密钥签名的 log4net 1.2.11 并用它重新编译了 Combress。之后添加了从 1.2.10 到 1.2.11 的程序集绑定重定向,它开始工作。

【讨论】:

    【解决方案5】:

    这不一定适用于所有情况,但是因为使用 log4net 的项目是 OSS,所以我下载了源代码,将 log4net 的冲突版本替换为我正在使用的版本并重建了项目。在我的例子中,它是 Topshelf,所以我现在有一个 Topshelf 程序集版本,它是用我正在使用的相同版本的 log4net 构建的,现在我可以毫无问题地引用两者。

    【讨论】:

      【解决方案6】:

      我尝试访问上面提供的链接,但似乎 Apache 站点中的所有链接都不起作用。然后这就是我为解决问题所做的:

      在您的 Visual Studio 中,使用 Nuget 下载并安装最新版本的 log4net (1.2.13.0)。 NuGet 包管理器会自动下载并升级所有 log4net(1.2.11.0) 到最新版本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-04
        • 2015-12-17
        • 2013-10-15
        • 2019-01-22
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        相关资源
        最近更新 更多