Pull to refresh

Comments 12

Да, для полноты картины полезная ссылка. Вариант Hugo статический, плюсы и минусы инвертируются по сравнению с приведенным.
Пардон, я пробежал мельком и не заметил, что это решение для runtime. Сорри за ссылку на статику.
Но ведь изначальный выбор внешней библиотеки будет зависеть от того, под какую платформу собран запускающийся исполняемый файл? Точнее под какой платформой он стартовал.
У меня была следующая проблема, была внешняя библиотека (написанная даже не под .NET) под x86. Она подключалась к исполняемому файлу, который был собран как AnyCPU. Все это хорошо работает на 32 разрядной системе, но при попытке запуска на 64-разрядной, приложение запускается (т.к. оно AnyCPU) в x64, и соответственно оно не может загрузить нужную библиотеку. Скорее всего я не очень долго искал (как AnyCPU приложение запустить в режиме x86 на 64-разрядной системе), но что то мне подсказывает, что это должно как то настраиваться?
по крайней мере тогда, я наткнулся на вот эту статью (как то там категорично говорилось, что AnyCPU запускается как x64), и решил что в моем случае быстрее было собрать основное приложение еще и под x86, и идти дальше.
Сейчас погуглил еще разок, нашлось только вот это. Что то мне не верится, что это можно сделать только таким образом…
Я эту проблему решил так:
Пишем в app.xaml.cs:
        public App()
        {
            System.AppDomain.CurrentDomain.AssemblyResolve += CustomResolve;
        }

        private static System.Reflection.Assembly CustomResolve(object sender, System.ResolveEventArgs args)
        {
            if (args.Name.StartsWith("ChilkatDotNet4"))
            {
                string fileName = System.IO.Path.GetFullPath("platform\\"
                    + System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
                    + "\\ChilkatDotNet4.dll");
                if (System.IO.File.Exists(fileName))
                {
                    return System.Reflection.Assembly.LoadFile(fileName);
                }
            }
            return null;
        }


Через эту функцию начинают проходть все запросы на загрузку любой внешней библиотеки (.NET). Мы проверяем, что запрашивается. Если наша библиотека, то шаманим ручками и грузим нашу либу для 32 или 64 разрядной оси. А в корне программы у нас папки:
platform/amd64/наша_либа_64.dll
platform/x86/наша_либа_32.dll
если загружается не наше, то есть то, что нам контролировать не надо, просто возвращаем null
Все
Нет, я про другое, я про старт самого приложения, если оно запущено в режиме x64, то загрузить в него x86 библиотеку уже не получится. При этом легкого способа указать, что твое приложение изначально надо запускать в x86 нельзя (ну кроме как пересобрать в x86).
На вопрос, а зачем же тогда основное приложение в AnyCPU, а не в x86, раз известна такая зависимость — она как раз неизвестна, приложение подгружает плагины, которые могут быть зависимы уже от либы, которая есть только в x86.
Тады ой. Если придумаете что, напишите. Но имхо эта проблема не имеет прямого и простого решения.
Приложение можно принудительно запустить в x86, если натравить на него CorFlags.exe
для non managed библиотек, затянутых к вам, к примеру через PIvoke можно использовать AddDllDirectory WinAPI (разложив в подкаталогах под архитектуры x86 и amd64 длл-ки) (если, конечно, KB2533623 стоит или винда выше xp)…
Тоже занимался данной проблемой недавно, искал тоже в сторону <assemblyBinding>, но не докопал.
Нашел только решение через AssemblyResolove. А вот хотелось бы как раз просто конфиг. Поэтому спасибо огромное.
В дополнение: у вас среди вариантов processorArchitecture нет варианта ARM, а это уже актуально с WinRT. В доке <assemblyBinding> варианта ARM нет, а вот в самом перечислении ProcessorArchitecture появился Arm. Так что можно опробовать.
Sign up to leave a comment.

Articles

Change theme settings