CurrentDomain.AssemblyResolve не может разрешать «некоторые» сборки

Найдя ответ на мой последний вопрос о разрешении сборки ( AppDomain.CurrentDomain .AssemblyResolve запрашивает сборку ‹AppName›.resources? ) теперь я могу встраивать сборки ссылок в свою программу, за исключением того, что это каким-то образом не работает с некоторыми ссылками.

Прежде всего, я устанавливаю свой преобразователь сборки при самом первом входе в мой Program.cs.

    // attach our embedded assembly loader.
    AppDomain.CurrentDomain.AssemblyResolve += AssemblyManager.Instance.Resolver;

Вот мой настоящий преобразователь;

public Assembly Resolver(object sender, ResolveEventArgs args)
{
    AssemblyName askedAssembly = new AssemblyName(args.Name);

    lock (this)
    {
        Assembly assembly;

        string resourceName = string.Format("Assets.Assemblies.{0}.dll", askedAssembly.Name);
        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
        {
            if (stream == null)
            {
                LogManager.Instance.Write(LogMessageTypes.Fatal, string.Format("Can not resolve asked assembly: {0}", askedAssembly.Name));
                MessageBox.Show(i18n.CanNotLoadRequiredAssembliesMessage, i18n.CanNotLoadRequiredAssembliesTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(-1);
            }

            byte[] assemblyData = new byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            assembly = Assembly.Load(assemblyData);
        }

        LogManager.Instance.Write(LogMessageTypes.Trace, "Loaded embedded assembly: " + askedAssembly.Name);

        return assembly;
    }
}

Теперь моя программа ссылается на сборки этих библиотек.

  • Esent.Collections.dll
  • Esent.Interop.dll
  • HtmlAgilityPack.dll
  • Ionic.Zip.Reduced.dll
  • System.Windows.Forms.Calendar.dll
  • AxInterop.ShockwaveFlashObjects
  • Interop.ShockwaveFlashObjects
  • irrKlang.NET4.dll
  • ikpMP3.dll
  • Nini.dll (РЕШЕНО)

С моим резольвером выше; Я могу встраивать Esent.Collections, Esent.Interop, HtmlAgilityPack, Ionic.Zip.Reduced, System.Windows.Forms.Calendar, AxInterop.ShockwaveFlashObjects, Interop.ShockwaveFlashObjects и разрешать их во время выполнения.

Проблема возникает со сборками irrKlang.NET.4, Nini и ShockwaveFlash, в которых, если я попытаюсь встроить эти сборки и попытаться решить их во время выполнения, у меня возникнут проблемы.

Для irrKlang я могу понять проблему, поскольку сборка irrKlang.NET4 ссылается на неуправляемую ikpMP3.dll, которую я не могу найти самостоятельно.

Что касается Nini.dll, на самом деле я могу встроить эту сборку и использовать запущенные конфигурации отладки/выпуска VS, она просто работает нормально, но когда я запускаю программу самостоятельно из проводника, программа просто отказывается запускаться (без ошибок или каких-либо битов). информации).

Любая помощь приветствуется.

Обновить Теперь, благодаря ответу Марка Гравелла, я могу загрузить Nini.dll.

Что касается части irrKlang, поскольку irrKlang.NET4.dll — это управляемая сборка, для которой требуется ikpMp3.dll — неуправляемая — если я попытаюсь разрешить irrKlang.NET4.dll во время выполнения, он сможет получить доступ к требуемой зависимости ikpMp3. Есть ли обходной путь для этого?


person HuseyinUslu    schedule 12.02.2011    source источник
comment
Используете ли вы какие-либо типы из метода Main? он должен иметь возможность полностью JIT Main для запуска приложения...   -  person Marc Gravell    schedule 13.02.2011
comment
На самом деле доступ к Nini.dll осуществляется из основного метода. Я попробую и уберу подальше.   -  person HuseyinUslu    schedule 13.02.2011


Ответы (1)


Распространенной проблемой здесь является использование типов до того, как у вас будет возможность зарегистрировать событие сборки-разрешения. В частности, обратите внимание, что система должна иметь возможность JIT метода, прежде чем она сможет начать выполнение метода, включая Main().

Таким образом, если ваша точка входа (Main()) выполняет перехват событий а также взаимодействует с рассматриваемыми типами, она попытается разрешить типы (для JIT) до или шанс подписаться.

Делайте минимум в main; переместите «настоящий» код в другой метод, который вызывается только после того, как событие определенно подписано.

Например:

static void Main() {
    SubscribeAssemblyResolver();
    ExecuteApplication();
}

В крайних случаях вам может даже понадобиться использовать MethodImplAttribute, чтобы отключить встраивание вышеперечисленных методов.

person Marc Gravell    schedule 12.02.2011
comment
Да, благодаря переносу вызовов на сборку Nini из Main() сотворил чудо, теперь JIT может загрузить программу, а дальнейшие ссылки на Nini.dll корректно разрешаются с помощью предоставленного мне преобразователя. - person HuseyinUslu; 13.02.2011