工作 · 2021年10月2日 0

C# 项目中引用的DLL 版本不一致的问题

本文介绍了让.NET程序兼容不同版本的Dll文件的方法:

场景一   以高版本兼容

把所有的新版DLL文件拷贝到运行目录下,希望主程序能够直接调用新版的库文件。只要在config里面加入runtime节点就可以完成主程序一调用。

<!–应用程序策略:
应用程序策略可以在应用程序配置文件中进行配置,应用程序配置文件位于应用程序目录下。对于.EXE应用程序,其配置文件由exe文件名加上.config后缀名构成,例如一个test.exe的应用程序,其配置文件就是test.exe.config。
而对于任何一个Web应用程序来说,其配置文件的文件名都是web.config。–>
<runtime>
<!–版本策略都记录在配置文件的assemblyBinding节点下–>
<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>
<!–对这个程序集进行版本重定向–>
<dependentAssembly>
<!–程序集标识assemblyIdentity包含name:Newtonsoft.Json,publicKeyToken:60c29e5f0af3e9bb …属性,定义了该程序集的标识信息–>
<assemblyIdentity name=”Newtonsoft.Json” publicKeyToken=”60c29e5f0af3e9bb” culture=”neutral”/>
<!–重定向的策略[将0.0.0.0到4.5.0.0之间的所有版本重定向到6.0.0.0版本上]–>
<bindingRedirect oldversion=”0.0.0.0-4.5.0.0″ newversion=”6.0.0.0″/>
</dependentAssembly>
</assemblyBinding>
<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>
<dependentAssembly>
<assemblyIdentity name=”NET.MST.Second.Compile” publicKeyToken=”60c29e5f0af3e9bb” culture=”neutral”/>
<bindingRedirect oldversion=”0.0.0.0-12.2.2.2″ newversion=”12.3.0.0″/>
</dependentAssembly>
</assemblyBinding>
<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>
<dependentAssembly>
<assemblyIdentity name=”Common.Logging” publicKeyToken=”af08829b84f0328e” culture=”neutral” />
<bindingRedirect oldVersion=”2.0.0.0″ newVersion=”2.1.1.0″ />
</dependentAssembly>
</assemblyBinding>
</runtime>

场景二   同一dll两种版本共存

例如:项目自己引用log4net.dll 版本1.2.13.0 。添加第三方某个dll,第三方依赖log4net.dll版本1.2.9.0,项目中需要两种版本共存。
这里还分两种情况,dll的publicKeyToken相同还是不同 (publicKeyToken查询见说明1)
publicKeyToken相同,配置方法:

<runtime>  
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
    <dependentAssembly>  
      <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" />  
      <codeBase version="1.2.13.0" href="bin\log4netdll\1_2_13\log4net.dll" />  
      <codeBase version="1.2.9.0" href="bin\log4netdll\1_2_9\log4net.dll" />  
    </dependentAssembly>  
  </assemblyBinding>  
</runtime>  

publicKeyToken不同,配置方法:

<runtime>  
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
    <dependentAssembly>  
      <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" />  
      <codeBase version="1.2.13.0" href="bin\log4netdll\1_2_13\log4net.dll" />  
    </dependentAssembly>  
    <dependentAssembly>  
      <assemblyIdentity name="log4net" publicKeyToken="b32731d11ce58905" />  
      <codeBase version="1.2.9.0" href="bin\log4netdll\1_2_9\log4net.dll" />  
    </dependentAssembly>  
  </assemblyBinding>  
</runtime>  

说明

publicKeyToken获取方式

使用vs的Tools Command Prompt命令行工具,输入:SN -T “path”,例如:

C:\Program Files (x86)\Microsoft Visual Studio 11.0>SN -T "D:\project\liberary\External\log4net.dll"  
  
Microsoft(R) .NET Framework 强名称实用工具 版本 4.0.30319.17929  
版权所有(C) Microsoft Corporation。保留所有权利。  
  
公钥标记为 b32731d11ce58905 

特性和元素

下列各节描述了特性、子元素和父元素。

特性

特性说明
xmlns必需的特性。

指定程序集绑定所需的 XML 命名空间。 使用字符串“urn: 架构-microsoft-com:asm.v1”作为值。
appliesTo指定 .NET Framework 程序集重定向适用的运行时版本。 此可选特性用 .NET Framework 版本号来指示其适用的版本。 如果没有指定 appliesTo 特性,<assemblyBinding> 元素将适用于 .NET Framework 的所有版本 。 appliesTo 属性是在 .NET Framework 1.1 版中引入的;版本 1.0 .NET Framework忽略它。 这意味着,即使指定了 appliesTo 特性,在使用 .NET Framework 版本 1.0 时所有的 <assemblyBinding> 元素也都适用 。

子元素

元素说明
<dependentAssembly>封装程序集的绑定策略和程序集位置。 每个 <dependentAssembly> 程序集使用一个标记。
<probing>指定加载程序集时公共语言运行时搜索的子目录。
<publisherPolicy>指定运行时是否使用发布者策略。
<qualifyAssembly>指定使用部分名称时应动态加载的程序集全名。

父元素

元素说明
configuration公共语言运行时和 .NET Framework 应用程序所使用的每个配置文件中的根元素。
runtime包含有关程序集绑定和垃圾回收的信息。