dll hell что это

DLL hell

DLL hell (DLL-кошмар, буквально: DLL-ад) — тупиковая ситуация, связанная с управлением динамическими библиотеками DLL в операционной системе Microsoft Windows.

Аналогичная проблема в других ОС носит название Dependency hell.

Сущность проблемы заключается в конфликте версий DLL, призванных поддерживать определённые функции. DLL hell — пример плохой концепции программирования, которая, подобно скрытой мине, приводит к резкому возрастанию трудностей при усложнении и совершенствовании системы.

Содержание

Описание проблемы

По исходному замыслу, DLL должны быть совместимыми от версии к версии и взаимозаменяемыми в обе стороны.

Реализация механизма DLL такова, что несовместимость и невзаимозаменяемость становится скорее правилом, чем исключением, что приводит к большому количеству проблем.

Для избежания конфликтов обычно используют множество избыточных копий DLL для каждого приложения, что сводит на нет исходную идею получения преимущества от DLL как стандартных модулей, хранящихся один раз в памяти и разделяемых многими задачами. Кроме того, при таком опыте после исправления ошибок в DLL или восстановления системы из архива количество различных DLL, носящих одно и то же имя и выполняющих те же функции, возрастает, а автоматическое обновление версии или исправление ошибок становится невозможным.

История проблемы

Эта проблема возникла в ранних версиях Microsoft Windows.

С подобными же проблемами сталкивались ранние версии Mac OS X, но с использованием других технологий. Не избегают подобных проблем дистрибуторы библиотек Open Source.

Поэтому, когда речь идёт о не-майкрософтовской среде, эту ситуацию называют dependency hell (кошмар зависимостей).

Проблема постоянно повторяется, когда программу пытаются запустить не с той DLL, c которой она тестировалась, что показывает изначальную порочность общей концепции, позволяющей произвольную замену версий модулей.

Меры против DLL hell

Данные меры рекомендуют предпринимать одновременно для получения наилучшего результата:

Источник

DLL Hell может проявляться по-разному, при этом приложения не запускаются и не работают правильно.

СОДЕРЖАНИЕ

Проблемы

Проблема возникает, когда версия библиотеки DLL на компьютере отличается от версии, которая использовалась при создании программы. Библиотеки DLL не имеют встроенного механизма обратной совместимости, и даже незначительные изменения в DLL могут сделать ее внутреннюю структуру настолько отличной от предыдущих версий, что попытка их использования обычно приводит к сбою приложения. Статические библиотеки позволяют избежать этой проблемы, потому что версия, которая использовалась для сборки приложения, включена в нее, поэтому даже если более новая версия существует в другом месте в системе, это не влияет на приложение.

Основной причиной несовместимости версий является структура файла DLL. Файл содержит каталог отдельных методов (процедур, подпрограмм и т. Д.), Содержащихся в DLL, и типов данных, которые они принимают и возвращают. Даже незначительные изменения в коде DLL могут привести к переупорядочению этого каталога, и в этом случае приложение, которое вызывает определенный метод, полагая, что это 4-й элемент в каталоге, может в конечном итоге вызвать совершенно другую и несовместимую процедуру, которая будет обычно вызывает сбой приложения.

Существует несколько проблем, с которыми обычно сталкиваются библиотеки DLL, особенно после того, как в системе были установлены и удалены многочисленные приложения. Сложности включают конфликты между версиями DLL, трудности с получением необходимых DLL и наличие множества ненужных копий DLL.

Несовместимые версии

Определенная версия библиотеки может быть совместима с некоторыми программами, которые ее используют, и несовместима с другими. Windows была особенно уязвима для этого из-за ее упора на динамическое связывание библиотек C ++ и объектов связывания и встраивания (OLE) объектов. Классы C ++ экспортируют множество методов, и одно изменение класса, например новый виртуальный метод, может сделать его несовместимым с программами, созданными для более ранней версии. Для предотвращения этого существуют очень строгие правила связывания и встраивания объектов: интерфейсы должны быть стабильными, а диспетчеры памяти не используются совместно. Однако этого недостаточно, поскольку семантика класса может измениться. Исправление ошибки в одном приложении может привести к удалению функции из другого. До Windows 2000 Windows была уязвима для этого, потому что таблица классов COM использовалась всеми пользователями и процессами. Только один COM-объект в одной DLL / EXE может быть объявлен как имеющий конкретный глобальный идентификатор COM-класса в системе. Если какой-либо программе требовалось создать экземпляр этого класса, она получала то, что было текущей централизованно зарегистрированной реализацией. В результате установка программы, которая установила новую версию общего объекта, может непреднамеренно нарушить работу других программ, которые были установлены ранее.

DLL топает

Неправильная регистрация COM

Общие модули в памяти

Отсутствие работоспособности

Причины

Несовместимость DLL была вызвана:

DLL Hell был очень распространенным явлением в версиях операционных систем Microsoft до Windows NT, основная причина заключалась в том, что 16-разрядные операционные системы не ограничивали процессы своим собственным пространством памяти, тем самым не позволяя им загружать свою собственную версию общий модуль, с которым они были совместимы. Ожидалось, что установщики приложений будут хорошими гражданами и проверят информацию о версии DLL перед перезаписью существующих системных DLL. Стандартные инструменты для упрощения развертывания приложений (которые всегда включают доставку зависимых библиотек DLL операционной системы) были предоставлены Microsoft и другими сторонними поставщиками инструментов. Microsoft даже потребовала, чтобы поставщики приложений использовали стандартный установщик и чтобы их программа установки была сертифицирована для правильной работы, прежде чем им будет разрешено использовать логотип Microsoft. Подход «добросовестного установщика» не смягчил проблему, поскольку рост популярности Интернета предоставил больше возможностей для получения несовместимых приложений.

Использование вредоносным ПО

Решения

Различные формы DLL-ада были решены или смягчены на протяжении многих лет.

Читайте также:  какой кредит выгоднее аннуитетный или дифференцированный при досрочном погашении

Статическое связывание

Защита файлов Windows

Сторонние приложения не могут обрабатывать файлы ОС, если они не связывают законные обновления Windows со своим установщиком или если они не отключают службу защиты файлов Windows во время установки, а в Windows Vista или более поздних версиях также приобретают права собственности на системные файлы и предоставляют себе доступ. SFC утилита может восстановить эти изменения в любое время.

Одновременный запуск конфликтующих DLL

Решения здесь состоят в наличии разных копий одних и тех же библиотек DLL для каждого приложения как на диске, так и в памяти.

Простым ручным решением конфликтов было размещение различных версий проблемной DLL в папки приложений, а не в общую общесистемную папку. В целом это работает, если приложение является 32-разрядным или 64-разрядным и DLL не использует разделяемую память. В случае 16-разрядных приложений два приложения не могут выполняться одновременно на 16-разрядной платформе или на одной и той же 16-разрядной виртуальной машине в 32-разрядной операционной системе. OLE предотвращало это до Windows 98 SE / 2000, потому что более ранние версии Windows имели единый реестр COM-объектов для всех приложений.

Портативные приложения

В зависимости от архитектуры приложения и среды выполнения переносимые приложения могут быть эффективным способом уменьшить некоторые проблемы с DLL, поскольку каждая программа связывает свои собственные частные копии любых требуемых DLL. Механизм основан на том, что приложения не полностью определяют пути к зависимым библиотекам DLL при их загрузке, а операционная система выполняет поиск в каталоге исполняемых файлов до любого общего расположения. Однако этот метод также может использоваться вредоносными программами, и повышенная гибкость также может быть достигнута за счет безопасности, если частные библиотеки DLL не обновляются с помощью исправлений безопасности так же, как общие.

Виртуализация приложений также может позволить приложениям работать в «пузыре», что позволяет избежать установки файлов DLL непосредственно в операционную систему.

Другие меры противодействия

Есть и другие меры противодействия DLL Hell, некоторые из которых, возможно, придется использовать одновременно; некоторые другие функции, которые помогают смягчить проблему:

Источник

. when altering one’s mind becomes as easy as programming a computer, what does it mean to be human.

11 февраля 2011 г.

DLL, DLL Hell, перенаправление DLL, Side-by-Side сборки и манифесты.

DLL (Dynamic Link Library — библиотека динамической компоновки) — понятие операционных систем Microsoft Windows и IBM OS/2; это библиотека, позволяющая многократное применение несколькими приложениями. K DLL относятся также элементы управления ActiveX и драйверы. В мире UNIX аналогичные функции выполняют т.н. shared objects («разделяемые объекты»). Формат файлов DLL придерживается тех же соглашений, что и формат исполняемых файлов, сочетая код и данные.

Введение

DLL Hell (DLL-кошмар, буквально: DLL-ад) — тупиковая ситуация, связанная с управлением динамическими библиотеками DLL в операционной системе Microsoft Windows. Аналогичная проблема в средах UNIX носит название Dependency Hell. Сущность проблемы заключается в конфликте версий DLL, призванных поддерживать определённые функции. По исходному замыслу, DLL должны быть совместимыми от версии к версии и взаимозаменяемыми в обе стороны. На практике однако оказалось, что достичь этого невозможно. Вы устанавливаете одну программу, и неожиданно перестает работать другая программа, казалось бы, совершенно не связанная с первой (это может быть сообщение вроде «не найдена библиотека», «не найдена процедура в библиотеке» или что-то более тонкое вроде неправильной работы программы, вылета или зависания). Это происходит потому, что, незаметно для вас, две программы объединены использованием одного файла библиотеки DLL. Для работы этих двух программ могут требоваться совершенно разные версии файла MSVCRT.DLL в системной папке. Или же одна программа может обновить элемент управления ActiveX, который используется другой программой, при этом вторая программа может быть не полностью совместима с этим обновлением.

Разве это применимо ко мне?

Windows 2000: перенаправление DLL

Раньше приходилось принимать решение о том, какая программа «победила», а какая — «проиграла». Начиная с Windows 2000 появились средства, помогающие разрешить такие конфликты. Тем не менее эти средства представляют собой лишь временные решения, позволяя вернуть систему в рабочее состояние, пока вы будете заниматься поиском более постоянного решения конфликта.

Перенаправление библиотек DLL не позволит полностью избежать кошмара библиотек DLL, но, по крайней мере, оно предоставляет средства первой помощи для контроля над ситуацией на время решения проблемы. По этой же причине, если раньше для установщиков были рекомендации: пишите свои DLL в системные папки, ведь тогда их смогут использовать и другие программы. И вы сэкономите на ресурсах! То начиная с Windows 2000 рекомендации меняются на противоположные: ребята, диск сегодня уже не ограничитель, так что установщикам следует располагать DLL в папке с программой. Да, место не сэкономите, но зато программа будет работать надёжно, ведь её не коснётся DLL Hell.

Windows XP: изолированные приложения и side-by-side сборки

Начиная с Windows XP в вашем распоряжении появляется новый механизм, позволяющий избавиться от проблемы DLL Hell: Isolated Applications и Side-by-side Assemblies. Это решение Microsoft Windows для уменьшения конфликтов версий в Windows приложениях. С его помощью разработчик может описывать требования своих приложений и DLL, так что они будут защищены от влияния других версий библиотек в системе. Конечные клиенты же получают выгоду от использования этого механизма тем, что приложения теперь будут работать надёжнее и будут устойчивы к обновлениям.

Side-by-side сборки и изолированные приложения

Приложение называется полностью изолированным, если все его компоненты являются side-by-side сборками. Если же ваше приложение использует один или более компонент, не являющихся side-by-side сборками (например: приложение использует обычную DLL без манифеста), то приложение называется частично изолированным. Заметьте, что частично изолированное приложение всё ещё уязвимо для DLL Hell. Учитывая, что мы уже сказали про «XP Manifest», многие (если не все) из ваших программ уже являются частично изолированными приложениями, хотя и в весьма малой степени.

Читайте также:  что делает реактивная мощность

Переделать приложение в полностью изолированное не всегда возможно. К примеру, некоторые компоненты, защищаемые Windows File Protection (WFP), не доступны в виде side-by-side сборок и не могут быть установлены вместе с приложением как частные сборки.

Управление сборками с помощью манифестов

Процесс приложения может использовать более одной версии side-by-side сборки. К примеру, приложение загружает две библиотеки, одна из которых использует версию 1 side-by-side сборки, а вторая загружаемая библиотека требует версии 2 той же сборки. Для различения сборок друг от друга используются манифесты и номера версий сборок. Используя эту информацию, загрузчик DLL может определить правильную версию DLL для загрузки. Это показано на следующем рисунке:

Манифесты

Манифесты в виде отдельных файлов позволяют администраторам и приложениям управлять версиями side-by-side сборок после развёртывания приложения. Каждая side-by-side сборка должна иметь манифест, ассоциированный с ней. При установке Windows XP устанавливаются side-by-side сборки от Microsoft вместе с их манифестами. Если вы собираетесь разрабатывать ваши собственные side-by-side сборки, то вы также должны устанавливать их манифесты.

Внимание: если вы применяете манифест в виде отдельного файла и меняете сам манифест без изменения двоичного модуля, то вы должны обновить дату изменения исполняемого модуля, чтобы манифест вступил в действие. Происходит это по той простой причине, что Windows кэширует данные и не проверяет наличие/отсутствие/изменение манифеста, если файл программы не поменялся. Это типичная оптимизация частого случая (файл не меняется).

К примеру, если вы установите идентификатор ресурса в 1, то загрузчик ОС будет использовать зависимости сборок, указанные в манифесте, как умалчиваемые для всего процесса. Все загружаемые плагины также будут использовать эти же зависимости.

Таблица ниже показывает, как загрузчик ОС использует манифест с различными значениями идентификатора ресурса. Заметьте, что разработчик может управлять этим процессом вручную, используя функции активации контекста (Activation Context API), которые не рассматриваются в этой статье.

Идентификатор По умолчанию для процесса? Используется при статическом импорте? Используется для EXE? Используется для DLL?
1 Да Да Да Нет
2 Нет Да Да Да
3 Нет Нет Да Да

CREATEPROCESS_MANIFEST_RESOURCE_ID должен использоваться приложениями, которые не работают с плагинами.

ISOLATIONAWARE_MANIFEST_RESOURCE_ID используется приложениями, которые загружают сторонние библиотеки (плагины).

Частные и разделяемые сборки

Разделяемые side-by-side сборки устанавливаются в папку WinSxS. Разделяемые side-by-side сборки могут быть установлены при установке обновления операционной системы или пакетом Windows Installer, который устанавливает или обновляет ваше приложение.

До Windows XP общие сборки (называемые просто DLL) регистрировались глобально и устанавливались в папку System. В этом случае приложению была доступна только последняя установленная версия сборки. Side-by-side сборка могла быть установлена как частная сборка для эксклюзивного использования приложением.

Как видите, здесь обычные и привычные вещи называются новыми именами.

Частные сборки устанавливаются в папку приложения. Обычно это сама папка приложения с исполняемым файлом. Частные сборки также могут располагаться в подпапке с именем сборки, или в подпапке с именем языка (тема локализации сборок не рассматривается в этой статье). Например, вы можете использовать следующую структуру папок для размещения частной сборки Microsoft.tools.pop без указания языка:

Практический пример: включение визуальных стилей

Общие элементы управления (common controls), которые включены в состав Windows XP, Windows Vista и Windows 7, имеют новую функциональность, которая называется «визуальными стилями» (visual styles). Внешний вид элементов управления может быть изменён, основываясь на настройках внешнего вида системы, изменяемых пользователем.

Примечание: визуальные стили не работают в режиме 256-цветов.

На рисунке ниже показано окно с панелью задач на Windows Vista. Приложение было скомпилировано со стандартной библиотекой общих элементов управления.

Новые библиотеки (ComCtl32.dll версии 6 и UxTheme.dll) доступны в по умолчанию в Windows XP и выше. Они позволяют задействовать в вашем приложении визуальные стили. UxTheme.dll используется ComCtl32.dll для реализации визуальных стилей. ComCtl32.dll запрашивает у UxTheme.dll размеры и другую информацию об элементах управления и вызывает UxTheme.dll для прорисовки различных частей элементов управления.

Если вы используете только стандартные элементы управления, то вам не нужно делать никаких других действий для включения визуальных стилей. Если же вы используете элементы управления с custom-прорисовкой, то вам нужно использовать предоставляемое API для получения информации о текущем визуальном стиле и рисовать свои элементы управления в этом стиле. См. Using Visual Styles with Owner-Drawn Controls.

Автоматическое использование для чайников

Поэтому, когда вы не можете использовать автоматический способ, то можно сделать всё руками.

Использование манифестов для включения визуальных стилей в приложениях

Атрибут Описание
version Версия манифеста. Версия представляется в форме major.minor.revision.build (т.е., n.n.n.n, где n assemblyIdentity в блоке зависимостей:

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

Использование ComCtl32.dll версии 6 в приложениях, которые используют только стандартные расширения

Использование ComCtl32 версии 6 в приложениях, которые используют расширения, плагины или DLL от других производителей

Для приложений этого типа используется такой манифест: И в RC-файле подключается он так:

Использование ComCtl32 версии 6 в Панели управления или DLL, которая запускается RunDll32.exe

Использование ComCtl32 версии 6 в оснастке MMC

Практический пример: использование частных сборок

Ну. вот, собственно и всё. Компилируйте DLL (разумеется, её имя должно быть Alex.Demo.Assembly.dll и приложение должно загружать или импортировать функцию именно из Alex.Demo.Assembly.dll ) и теперь вы получите уже не просто DLL, а полноценную частную сборку.

Запустите приложение теперь. Ну, вроде бы ничего не изменилось, да? Да. Всё потому, что в самом приложении мы не указали зависимость от этой сборки. Поэтому приложение загружает эту сборку как обычную DLL.

Что будет, если запустить приложение теперь? Ну, вроде бы, снова ничего не изменится. Однако, под капотом произошло важное изменение: теперь DLL грузится как сборка. Что означает, что в силу вступают проверки версионной зависимости.

Как это можно увидеть? Попробуйте поменять версию (атрибут version ) либо в манифесте приложения, либо в манифесте сборки (конечно же, речь идёт об атрибуте version для блока assemblyIdentity с name = Alex.Demo.Assembly ). Скажем, пусть мы поменяем номер самой сборки с 1.0.0.0 до 2.0.0.0. Пересоберём сборку и запустим приложение.

Опа. Теперь мы получаем сообщение о том, что приложение не может найти нужную DLL:

Итак, мы реализовали сборку в виде единственной DLL и нам это практически ничего не стоило. Всего делов-то, добавить манифест (кстати, было бы неплохо в опции проекта Delphi добавить галочку «Enable assembly manifest» по аналогии с «Enable visual themes»).

Side-by-Side в частных сборках

Практический пример: использование разделяемых сборок

Как это выглядит на практике.

Начните с подготовки файлов сборки, манифеста сборки и сертификата, которым вы будете подписывать сборку. Ключ сертификата должен иметь длину не менее 2048 бит. Вам не обязательно использовать сертификат, подписанный доверенным центром сертификации (trusted certificate). Сертификат необходим только для проверки того, что сборка не была изменена. Поэтому для подписи сборок обычно используются само-подписанные сертификаты. Вероятно, будет хорошей идеей делать отдельный сертификат для каждого вашего продукта.

Готово. Теперь остаётся только установить её.

Windows требует, чтобы разделяемые сборки устанавливались с помощью Windows Installer (MSI). Это гарантирует, что Windows сможет починить сборку, если она будет повреждена.

Рекомендации по использованию Side-by-Side

Практический пример: другие типы стандартных манифестов

High DPI awareness: объявление, что ваше приложение в курсе про режимы экрана с высоким DPI

Примечание: по умолчанию виртуализация DPI включается только на DPI выше 120 (125%).

Хотя в Win32 API есть функция для объявления приложения как DPI-aware ( SetProcessDPIAware ), её использование не поощряется, кроме специальных сценариев. В общем случае рекомендуется использовать манифест для объявления приложения DPI-aware.

UAC: указание требуемого уровня привилегий для приложения

В выпуске Windows Vista есть положения, позволяющие коду без манифеста или неподписанному коду работать с полным административным маркером доступа.

Примечание: в будущих версиях системы единственным способом для приложения запуститься с полными административными привилегиями будет указание подписанного манифеста.

В Windows Vista и выше используется такой формат в манифесте для указания требуемого уровня привилегий: Возможные значения и их трактовка:

Значение Описание Комментарий
asInvoker Приложение запускается с тем же токеном, что и вызывающий процесс. Рекомендуется для обычных приложений пользователя. Примеры программ: Блокнот, Калькулятор, Microsoft Word, Delphi, Total Commander.
highestAvailable Приложение запустится с максимальными привилегиями, которые могут быть доступны пользователю. Рекомендуется для приложений смешанного режима. Примеры программ: Консоль MMC, Редактор реестра.
requireAdministrator Приложение всегда запускается с полным токеном администратора. Рекомендуется только для приложений администраторов. Примеры программ: установщики программ.

Смысл значений uiAccess :

Значение Описание
False Приложению не требуется управлять вводом в пользовательский интерфейс другого окна на рабочем столе. Приложения, которые не предоставляют возможности accessibility, должны устанавливать этот флаг в False. Приложения, которым требуется управлять вводом в другие окна на рабочем столе (к примеру, экранные клавиатуры) должны устанавливать это значение в True.
True Приложению разрешается обходить уровни контроля интерфейса пользователя, чтобы получать доступ к окнам с высокими привилегиями на рабочем столе. Эта настройка должна применяться только приложениями, реализующими Assistive Technology.

Примечание: приложения с uiAccess равным True должны иметь корректную цифровую подпись. Кроме того, приложение должно располагаться в защищённом месте системы. Сегодня такими местами являются папки \Program Files\ и \windows\system32\.

Указание на совместимость с конкретной ОС

Поведение операционной системы может меняться в каждой новой версии системы. Поэтому приложение, написанное для старой версии системы, может работать не совсем верно (или вообще не работать) в новой версии системы. Мы только что разобрали пример с UAC. К примеру, в Windows 7 было немного изменено поведение системы. По умолчанию приложения получают поведение системы как в Windows XP (если в манифесте нет информации о требуемом уровне привилегий или совместимости с ОС) или как в Windows Vista (если в манифесте указана информация о требуемом уровне привилегий или задекларирована совместимость с Windows Vista). Чтобы получить поведение как в Windows 7 (без эмуляции), приложению нужно указать это явно.

Список изменений в поведении для Windows 7 по сравнению с Windows Vista можно увидеть в статье MSDN Windows 7 / Application Manifests. Список для Windows 8/8.1 можно посмотреть в Windows Compatibility Cookbook.

Собираем всё вместе

Заключение

Кстати говоря, если вы столкнётесь с проблемами при поиске/загрузке сборок в своих программах, то утилита командной строки sxstrace поможет вам их решить.

Источник

Читайте также:  частная группа в телеграмме что это значит
Сказочный портал