我如何解决log4net不断更改publickeytoken


99

我们有一个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中的runtime元素使用程序集重定向(使所有框架使用相同版本的log4net)或代码库(仅使新框架使用1.2.11.0版本)。

我在这里有什么选择?

(为什么log4net会在版本之间不断变化,因为据我所知,丢失了密钥是在版本1.2.9.0和1.2.10.0之间进行切换的原因,它们又失去了密钥吗?我将自愿使用我的保管箱在需要时保持安全...)

编辑:好的,所以log4net的人显然有一个想法,用两个键来发布是个好主意,但这意味着您使用的每个框架都需要就他们偏爱的两种风格中的哪个达成一致,否则这些框架将无法正常工作。在同一个appdomain中并排。我是唯一发现这个可怕想法的人吗?如果每个人都这样做,那么一切都会崩溃,对吗?

Edit2:正如我所说,我没有在业务代码中使用log4net,而是使用了一些依赖于1.2.10.0的框架,当我尝试使用依赖于1.2.11.0的新框架时出现了问题(新密钥),因此Stefans的答案不适用,因为新框架将需要新密钥,而不是旧密钥


1
恕我直言,这是apache的第一个错误,是提供使用新密钥签名的二进制文件:新密钥用于修补/增强的开源版本,不应按原样使用。第二个错误是您所谈论的框架仅使用新的log4net签名发布:应该存在带有旧签名的版本。
JoeBilly 2012年

6
实际上,您正在看的是第三种风味:SAP的天才用自己的强势名字重新编译,这是Crystal Reports for Visual Studio软件包的一部分,更糟糕的是,他们将其粘贴在GAC中,这将使您对计算机的依赖性是一场噩梦。
杰里米·霍洛瓦奇

Answers:


65

这就是我如何使用1.2.11.0版的东西。

  1. 首先诅咒apache来更改密钥:)
  2. 下载用旧密钥签名的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>

9
必须下载用旧的公共密钥签名的版本,因为不幸的是,无法对具有不同公共密钥的程序集执行绑定重定向。
David Christiansen

2
这似乎在1.2.11.0因未能打破变化: netpl.blogspot.com/2012/03/...
sydneyos

有没有人找到一个解决通过@sydneyos提到的链接,将导致以下异常描述的问题:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'

不幸的是,除了降级到1.2.10,没有其他解决方案。(或重新编译您使用的每个相关程序集)。
13年

1
将1.2.10程序集放在另一个目录中,并使用以下配置:'<dependentAssembly> <assemblyIdentity name =“ log4net” publicKeyToken =“ 1b44e1d426115821” culture =“ neutral” /> <bindingRedirect oldVersion =“ 0.0.0.0-1.2.9.0 “ newVersion =” 1.2.10.0“ /> <codeBase version =” 1.2.10.0“ href =” Resources \ log4net-oldkey \ log4net.dll“ /> </ dependentAssembly>'
敏捷绝地

27

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

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

为此,您需要执行以下操作:

  1. 首先下载旧版本(1.2.11.0版本)。
  2. 将下载的二进制文件重命名为log4net.1.2.10.dll。将其包含在启动项目中,并将“ 构建”操作设置为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的请求都将指向新版本。


4
这是一个很好的解决方案,因为它允许您维护引用这两个库的两个版本。
SouthShoreAK 2015年

2
谢谢!这救了我。我不得不将“复制到输出目录”更改为“请勿复制”,但否则它就像一个魅力!
DanielHedenström'18

3

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

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

(新密钥基本上是公开可用的,由于某种原因,他们不想在发行版中包含旧密钥。对我来说,不清楚为什么他们不只是将旧密钥公开提供)


10
但是当我使用绑定到新密钥的第三方库时,我仍然卡住了(对吗?)。这不是我的选择,使用新的log4net的,它的第三方框架。我看不出这个东西不会在每个人炸毁面临的越来越多的框架开始使用log4net的新重点
AndreasKnudsen

不幸的是,这是正确的。我猜您需要考虑不要让所有组件都使用相同版本的log4net ...
Stefan Egli 2012年

1
....我该怎么做呢?.net中是否有任何机制可以处理此问题?
AndreasKnudsen 2012年


1

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


0

这不一定在所有情况下都有效,但是因为使用log4net的项目是OSS,所以我下载了源代码,用我使用的版本替换了有冲突的log4net版本,然后重建了项目。就我而言,它是Topshelf,所以我现在有一个版本的Topshelf程序集,该程序集是使用与我使用的相同版本的log4net构建的,现在我可以毫无问题地引用两者。


0

我尝试转到上面提供的链接,但是看来Apache站点中的所有链接都无法正常工作。然后,这就是我解决该问题的方法:

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

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.