引用特定DLL后log4net.dll无法加载的问题求助
解决DLL地狱:Modbus.dll + Regatron.G5.dll的log4net冲突问题
问题场景
- 类库及测试项目基于.NET 4.7.2,依赖
Modbus.dll(需log4net 1.2.10.0)和Regatron.G5.dll - 单独使用Modbus.dll时,log4net正常加载,程序运行无问题
- 加入并调用Regatron.G5.dll后,Modbus.dll抛出找不到log4net的异常,且运行时Modules窗口无log4net条目
已尝试无效方案:
- 将Modbus.dll与log4net.dll放在专属文件夹
- 类库项目安装log4net NuGet包
- 仅调用项目安装log4net NuGet可解决,但无法要求用户执行此操作
原因分析
Regatron.G5.dll大概率内嵌了私有版本的log4net(比如通过ILMerge合并、嵌入资源动态加载等方式)。这种情况下,CLR加载Regatron.G5.dll时会优先使用它内嵌的log4net代码,而内嵌的程序集不会被视为独立模块,因此不会出现在Modules窗口中。此时Modbus.dll请求1.2.10.0版本,CLR的程序集加载逻辑被干扰,导致无法找到指定版本的log4net。
可行解决方案
1. 配置程序集绑定重定向
在项目的app.config(如果是类库,最终需要合并到调用方的主配置文件中)添加绑定重定向规则,强制CLR加载你需要的log4net 1.2.10.0版本:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.2.10.0" newVersion="1.2.10.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
注意:公钥令牌需与你的log4net版本匹配,1.2.10.0的公钥令牌可通过sn -T log4net.dll命令验证。
2. 手动处理程序集解析
在调用Modbus.dll之前,注册程序集解析事件,手动指定log4net的加载路径,绕过CLR的默认加载逻辑:
// 建议在类库初始化方法中执行 AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var assemblyName = new AssemblyName(args.Name); if (assemblyName.Name.Equals("log4net", StringComparison.OrdinalIgnoreCase)) { // 替换为你的log4net.dll实际路径,比如类库输出目录下的libs文件夹 var log4netPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libs", "log4net.dll"); return File.Exists(log4netPath) ? Assembly.LoadFrom(log4netPath) : null; } return null; };
3. 验证Regatron.G5.dll的依赖
使用ILSpy或dotPeek反编译Regatron.G5.dll,确认它是否内嵌log4net或依赖其他版本。如果是依赖外部版本,绑定重定向即可解决;如果是内嵌,程序集解析事件能强制加载你指定的log4net版本。
内容的提问来源于stack exchange,提问作者carllacan
相关产品推荐
相关产品推荐

