Side-by-side assembly
Side-by-side assembly (SxS) — технология, являющаяся стандартом для исполняемых файлов в операционных системах Windows 98 Second Edition, Windows 2000 и последующих версиях Windows, предназначенная для решения проблем, совокупно называемых «DLL-адом», связанных с использованием динамически подключаемых библиотек (DLL) в Microsoft Windows. К таким проблемам относятся конфликты версий, отсутствие DLL, дублирование DLL и некорректная или отсутствующая регистрация. В технологии side-by-side несколько версий одной DLL хранятся в каталоге %systemroot%\WinSxS и загружаются по мере необходимости. Это уменьшает проблемы с зависимостями для приложений, использующих side-by-side манифест.
Работа
Microsoft Visual C++ 2005 и 2008 используют SxS для всех C библиотек времени выполнения. Однако библиотеки времени выполнения в Visual C++ 2010 уже не применяют эту технологию; вместо этого номер версии указывается в имени DLL-файла, и разные версии одной DLL становятся различными файлами[1][2].
SxS также лежит в основе регистрации-независимой активации COM-компонентов. Только внутрипроцессные COM-серверы могут быть активированы таким способом.
Приложение, использующее SxS, должно иметь манифест. Манифест обычно является секцией, встроенной в исполняемый файл приложения, но также может быть отдельным внешним файлом. Когда операционная система загружает приложение и обнаруживает наличие манифеста, загрузчик DLL направляется к той версии библиотеки, которая указана в манифесте. Если манифеста нет, загрузчик DLL выбирает версию по умолчанию для всех зависимостей DLL. Если DLL является COM-сервером, для успешной регистрации-независимой активации у неё тоже должен быть свой манифест.
В Windows Vista и более новых версиях утилита sxstrace.exe может помочь диагностировать сбои при запуске приложений, связанные с ошибками конфигурации SxS.
Если пользователь желает переопределить сборки, указанные в манифесте (например, при необходимости применения обновлений безопасности к библиотеке), глобальную переадресацию сборок может осуществлять конфигурационный файл издателя. Цифровые подписи могут обеспечить легитимность такой переадресации[3].
Формат манифеста
Манифест приложения реализован во внутреннем представлении в формате XML. URN, связанный с манифестами SxS, — «urn:schemas-microsoft-com:asm.v1».
Ряд современных технологий Microsoft, таких как ClickOnce, используют тот же формат манифеста.
Ниже приведён пример манифеста для приложения, зависящего от DLL библиотеки времени выполнения C.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" />
</dependentAssembly>
</dependency>
</assembly>
Манифест подобного вида парсится загрузчиком SxS в контекст активации. Для каждого потока или фибра существует стек контекстов активации. Для программного управления этими контекстами предоставляется АПИ. Иногда библиотеке (DLL) может потребоваться изменять свой контекст активации, например, если ей нужна определённая версия другой библиотеки именно для собственных нужд (вместо использования контекста вызывающего). Такую проблему иногда называют «загрязнением контекста активации»[4]. Чтобы избежать загрязнения контекста активации, DLL может содержать встроенный манифест в виде ресурса, который будет обработан при её загрузке. Такой манифест должен иметь идентификатор ресурса 2 в образе файла, чтобы загрузчик мог его найти[5].
WinSxS (хранилище компонентов Windows)
Начиная с Windows Vista, операционная система использует WinSxS для хранения своих основных компонентов. Файлы операционной системы в каталоге winsxs связаны жёсткими ссылками с привычными для пользователя локациями в каталогах Windows. Один и тот же файл в подкаталоге winsxs может быть связан с несколькими местами (например, с System32 и с каталогами приложений). Проводник Windows учитывает занимаемое этими файлами пространство дважды[6]. Это можно продемонстрировать с помощью командной утилиты fsutil[7]. Существуют сторонние расширения для проводника, позволяющие отображать счётчик ссылок.
Однако не все файлы из winsxs таким образом проецируются в «живые» каталоги операционной системы. Например, после установки некоторых обновлений Windows старые версии файлов, заменённые обновлениями, продолжают храниться в winsxs, даже если они больше не связаны с актуальными каталогами Windows. Это позволяет при необходимости откатить обновления[8].
В связи с критическим значением директории winsxs, начиная с Vista она принадлежит службе Trusted Installer (SID TrustedInstaller). По умолчанию даже администраторы не имеют права изменять её содержимое без смены владельца. После удаления приложений пространство в winsxs не освобождается мгновенно: очистка неиспользуемых сборок выполняется по мере необходимости службой установщика[9].
Хотя официальная документация не описывает алгоритм генерации имён подкаталогов внутри winsxs, он был опубликован в блоге сотрудника Microsoft на MSDN. Алгоритм был изменён при переходе с XP на Vista[10].
В Windows 7 входит инструмент Windows AIK — Deployment Image Servicing and Management (DISM), который позволяет удалять файлы заменённых компонентов ОС с помощью службы Trusted Installer без необходимости перезагрузки или простоя системы[11]; после SP1 в средстве Disk Cleanup (cleanmgr.exe)[12] и в скачиваемом инструменте System Update Readiness (CheckSUR)[13] добавлена функция очистки обновлений и восстановления исправных версий повреждённых/отсутствующих файлов ОС. В Windows 8 встроена функция ремонта через DISM, позволяющая копировать корректные файлы ОС из Windows Update или из офлайн-образа WIM, а также сбрасывать хранилище компонентов так, чтобы в нём оставались только самые свежие версии компонентов[14]. В Windows 10 выполняется автоматическая задача по очистке хранилища компонентов[15].
Преимущества
- Для приложений, использующих SxS, могут одновременно сосуществовать несколько программ, зависящих от разных версий одной и той же DLL. В отличие от среды с обычными DLL, в которой из-за установки другой программы оригинальная DLL в общей папке может быть перезаписана и заменена её иной версией.
- XML-формат манифеста легко читается человеком, что облегчает разработчикам определение зависимостей приложения и их версий.
Недостатки
- В Windows XP из-за ошибки в sxs.dll возможна порча кучи и аварийное завершение приложений. Проблема не устраняется ни одним из сервис-паков XP — требуется ручная установка соответствующего обновления[16].
- Значительно большее кажущееся потребление дискового пространства, хотя большинство данных в winsxs — это дополнительные жёсткие ссылки к существующим файлам.
- Каталог winsxs и журналы обновлений Windows могут повреждаться по мере их увеличения, поскольку обновления безопасности добавляют в хранилище множество новых версий ключевых компонентов системы. В Windows Vista отсутствует поддерживаемый способ существенно уменьшить размер winsxs[8].
Дисковое пространство
Хотя каталог winsxs может быть очень большим и содержать множество версий одних и тех же файлов, некоторые файлы, находящиеся в других местах папки Windows (например, System32), на самом деле являются жёсткими ссылками на объекты из winsxs[17]. Поэтому при оценке размера папки Windows программа учёта не должна суммировать размер каждого жёсткого звена файла после того, как файл уже был учтён[18].
Команды DIR и проводник Windows не учитывают жёсткие ссылки и могут ошибочно посчитать один и тот же файл несколько раз, тем самым увеличив кажущееся использование диска. Такой учёт приводит к тому, что каждая жёсткая ссылка считается отдельным файлом.
Начиная с Windows 8.1, инструмент DISM позволяет анализировать хранилище компонентов и отображать его реальный размер[19].