Можно ли загрузить сборку, предназначенную для другой версии среды выполнения .NET, в новом домене приложения?

У меня есть приложение, основанное на среде выполнения .NET 2. Я хочу добавить немного поддержки .NET 4, но не хочу (в краткосрочной перспективе) преобразовывать все приложение (которое очень велико) в целевую .NET 4.

Я попробовал «очевидный» подход к созданию файла .config приложения, имеющего следующее:

<startup useLegacyV2RuntimeActivationPolicy="true">
  <supportedRuntime version="v4.0" />
</startup>

но я столкнулся с некоторыми проблемами, которые я отметил здесь.

У меня возникла идея создать отдельный домен приложения. Чтобы проверить это, я создал проект WinForm, ориентированный на .NET 2. Затем я создал библиотеку классов, ориентированную на .NET 4. В моем проекте WinForm я добавил следующий код:

        AppDomainSetup setup = new AppDomainSetup();
        setup.ApplicationBase = "path to .NET 4 assembly";
        setup.ConfigurationFile = System.Environment.CurrentDirectory + 
          "\\DotNet4AppDomain.exe.config";

        // Set up the Evidence
        Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
        Evidence evidence = new Evidence(baseEvidence);

        // Create the AppDomain      
        AppDomain dotNet4AppDomain = AppDomain.CreateDomain("DotNet4AppDomain", evidence, setup);
        try
        {
            Assembly doNet4Assembly = dotNet4AppDomain.Load(
               new AssemblyName("MyDotNet4Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=66f0dac1b575e793"));
            MessageBox.Show(doNet4Assembly.FullName);
        }
        finally
        {
            AppDomain.Unload(dotNet4AppDomain);
        }

Мой файл DotNet4AppDomain.exe.config выглядит так:

<startup useLegacyV2RuntimeActivationPolicy="true">
  <supportedRuntime version="v4.0" />
</startup>

К сожалению, это вызывает исключение BadImageFormatException при выполнении dotNet4AppDomain.Load. Я что-то делаю неправильно в своем коде, или то, что я пытаюсь сделать, просто не сработает?

Спасибо!


person Notre    schedule 26.03.2010    source источник


Ответы (2)


Вы нацеливаетесь на 2.0, чтобы он был загружен в память ... они вы просите его загрузить изображение 4.0 ... он не может работать, вам нужно создать новый экземпляр Runtime правильной версии, если вы хотите это сделать .

Единственный способ сделать это может заключаться в размещении второй среды CLR внутри вашего процесса, как описано в Можно ли разместить CLR в программе на языке C? Это стало возможным с .Net 4.0.

person Julien Roncaglia    schedule 26.03.2010
comment
Я надеялся, что наличие отдельного домена приложений позволит мне использовать разные версии CLR в одном процессе. Атрибут useLegacyV2RuntimeActivationPolicy подразумевает, что с установленной средой выполнения .NET 4 вы можете начать активацию с помощью .NET 2, а с помощью элемента supportedRuntime вы можете сказать «загрузить сборки .NET 4» по мере необходимости. Это именно то, чего я хочу достичь, но, к сожалению, я столкнулся с проблемой, описанной в другом посте. Я надеялся, что отдельные домены приложений позволят мне добиться того же, но с чуть большим контролем. - person Notre; 26.03.2010
comment
Я отредактировал свой ответ, поскольку .Net 4.0 позволяет загружать два экземпляра CLR на одном хосте. Что касается useLegacyV2RuntimeActivationPolicy, я думаю, вы путаете его с чем-то другим, поскольку в большинстве случаев это касается только сборок в смешанном режиме. - person Julien Roncaglia; 26.03.2010
comment
В других случаях я успешно использовал useLegacyV2RuntimeActivationPolicy в «чистом» управляемом коде .NET. Но в этом последнем приложении, где я пытался его применить, были плохие побочные эффекты. Я начинаю думать, что мою проблему невозможно решить в случае чисто управляемого .NET (если не считать перекомпиляции всего для целевой среды выполнения .NET 4), даже с использованием разных доменов приложений. У меня тоже был этот разговор на форуме MSDN - social.msdn.microsoft.com/Forums/en/netfxappcompatprerelease/ Было бы интересно узнать ваше мнение об этом. - person Notre; 27.03.2010
comment
См. Приведенную выше ссылку на форум MSDN для подтверждения того, что AppDomain не работает, а также для решения проблемы. - person Notre; 31.03.2010

Я был бы склонен подозревать, что версия 2 среды выполнения .NET не имеет ни малейшего представления о .NET 4. Судя по звучанию и характеру вашего вопроса, вы имеете дело с ним в обратном порядке ... Вы пытались скомпилировать и нацеливание на .NET 4 для загрузки библиотеки времени выполнения .NET 2 ... Я бы не подумал, что можно смешивать разные версии скомпилированного кода (одна для .NET 4, а другая для .NET 2) в одном и том же процесс...

person t0mm13b    schedule 26.03.2010
comment
Я уверен, что вы правы в том, что среда выполнения .NET 2 ничего не знает о среде выполнения .NET 4. Но, как отмечалось в моем предыдущем комментарии, есть некоторая магия, которая позволяет обоим сосуществовать в одном процессе при использовании атрибута useLegacyV2RuntimeActivationPolicy и элемента supportedRuntime. Я не пробовал обратное, но я не понимаю, как это могло бы мне помочь ... - person Notre; 26.03.2010