Проблема загрузки сборок скомпилированных под устаревший CLR давно известна. Старые библиотеки отказываются работать в CLR 4 и выше, если принудительно не задать в app.config разрешение на выполнение этих сборок в новом райнтайме:
<configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/> </startup> </configuration>
Без этой настройки получим исключение FileLoadException:
Сборка для смешанного режима построена на основе версии “v2.0.50727” среды выполнения и не может быть загружена в среде выполнения 4.0 без дополнительных конфигурационных данных.
Что же делать, если нет желания или возможности таскать с собой app.config?
К счастью, можно задать параметр useLegacyV2RuntimeActivationPolicy во время выполнения.
Ниже код, который опубликовал Рид Копси в своём блоге:
using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace LegacyRuntimeTest { public static class RuntimePolicyHelper { public static bool LegacyV2RuntimeEnabledSuccessfully { get; private set; } static RuntimePolicyHelper() { var clrRuntimeInfo = (ICLRRuntimeInfo)RuntimeEnvironment.GetRuntimeInterfaceAsObject( Guid.Empty, typeof(ICLRRuntimeInfo).GUID); try { clrRuntimeInfo.BindAsLegacyV2Runtime(); LegacyV2RuntimeEnabledSuccessfully = true; } catch (COMException) { LegacyV2RuntimeEnabledSuccessfully = false; } } [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("BD39D1D2-BA2F-486A-89B0-B4B0CB466891")] private interface ICLRRuntimeInfo { void xGetVersionString(); void xGetRuntimeDirectory(); void xIsLoaded(); void xIsLoadable(); void xLoadErrorString(); void xLoadLibrary(); void xGetProcAddress(); void xGetInterface(); void xSetDefaultStartupFlags(); void xGetDefaultStartupFlags(); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void BindAsLegacyV2Runtime(); } } }
Использование:
if (RuntimePolicyHelper.LegacyV2RuntimeEnabledSuccessfully) { // Удалось! } else { // Не удалось =( }
Свойство LegacyV2RuntimeEnabledSuccessfully статического класса RuntimePolicyHelper сообщает, удалось ли привязать к устаревшей сборке новый рантайм.
Привязка может не сработать, если рантайм уже был привязан ранее.
Обращаться к свойству нужно как можно раньше, до обращения к типам устаревшей сборки. Вынесите обращения к старой сборке в отдельный метод, это гарантирует, что RuntimePolicyHelper отработает раньше.
P.S.: По картинке ниже можно представить с какими версиями .NET библиотек придётся повозиться:
спасибо, помогло!) нужно было сделать такой трюк в библиотеке
Не за что)
Спасибо, выручили