Поделиться через


Как среда выполнения находит сборки

Замечание

Эта статья связана с .NET Framework. Он не применяется к более новым реализациям .NET, включая .NET 6 и более поздние версии.

Чтобы успешно развернуть приложение .NET Framework, необходимо понять, как среда CLR находит и привязывается к сборкам, составляющим приложение. По умолчанию среда выполнения пытается привязаться к точной версии сборки, с помощью которую было создано приложение. Это поведение по умолчанию можно переопределить параметрами файла конфигурации.

Общая языковая среда выполнения выполняет ряд шагов при попытке найти сборку и обработать ссылку на сборку. Каждый шаг описан в следующих разделах. Термин "поиск" часто используется при описании того, как среда выполнения находит сборки; он ссылается на набор эвристических методов, используемый для поиска сборки, основываясь на её имени и культурных параметрах.

Замечание

Сведения о привязке можно просмотреть в файле журнала с помощью средства просмотра журналов привязки сборок (Fuslogvw.exe), который включен в пакет SDK для Windows.

Инициирование привязки

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

Предпочтительный способ ссылки на сборку — использовать полную ссылку, включая имя сборки, версию, язык и региональные параметры и маркер открытого ключа (если он существует). Среда выполнения использует эти сведения для поиска сборки, следуя инструкциям, описанным далее в этом разделе. Среда выполнения использует тот же процесс разрешения независимо от того, является ли ссылка для статической или динамической сборки.

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

Наконец, вы можете создать динамическую ссылку с помощью такого метода, как Assembly.Load и предоставить только частичную информацию; затем вы квалифицируйте ссылку с помощью <элемента qualifyAssembly> в файле конфигурации приложения. Этот элемент позволяет предоставить полные справочные сведения (имя, версия, язык и региональные параметры и, если применимо, маркер открытого ключа) в файле конфигурации приложения, а не в коде. Этот метод можно использовать, если вы хотите полностью квалифицировать ссылку на сборку за пределами каталога приложения, или если вы хотите ссылаться на сборку в глобальном кэше сборок, но вы хотели бы, чтобы указать полную ссылку в файле конфигурации вместо кода.

Замечание

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

Среда выполнения использует следующие шаги для разрешения ссылки на сборку:

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

  2. Проверяет, привязано ли имя сборки к предыдущей и, если да, использует ранее загруженную сборку. Если предыдущий запрос на загрузку сборки завершился сбоем, текущий запрос также будет отклонен немедленно, без попытки загрузки сборки.

    Замечание

    Кэширование ошибок привязки сборки новое в .NET Framework версии 2.0.

  3. Проверяет глобальный кэш сборок. Если сборка найдена там, среда выполнения использует эту сборку.

  4. Пробы для сборки , выполнив следующие действия.

    1. Если политика конфигурации и издателя не влияют на исходную ссылку и если запрос привязки был создан с помощью Assembly.LoadFrom метода, среда выполнения проверяет наличие подсказок расположения.

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

    3. Пробы сборки с использованием эвристики, описанной в разделе проверки. Если сборка не найдена после проверки, среда выполнения запрашивает у установщика Windows предоставление сборки. Это действует как компонент установки по запросу.

      Замечание

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

Шаг 1. Изучение файлов конфигурации

Поведение привязки сборки можно настроить на разных уровнях на основе трех XML-файлов:

  • Файл конфигурации приложения.

  • Файл политики издателя.

  • Файл конфигурации компьютера.

Эти файлы соответствуют тому же синтаксису и предоставляют такие сведения, как перенаправления привязки, расположение кода и режимы привязки для определенных сборок. Каждый файл конфигурации может содержать <элемент assemblyBinding>, который перенаправляет процесс привязки. Дочерние элементы элемента< assemblyBinding> включают элемент <dependentAssembly>. Дочерние элементы <dependentAssembly> включают элемент <assemblyIdentity>, элемент <bindingRedirect> и элемент <codeBase>.

Замечание

Сведения о конфигурации можно найти в трех файлах конфигурации; Не все элементы допустимы во всех файлах конфигурации. Например, сведения о режиме привязки и закрытом пути могут находиться только в файле конфигурации приложения. Полный список сведений, содержащихся в каждом файле, см. в разделе "Настройка приложений с помощью файлов конфигурации".

Файл конфигурации приложения

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

Для исполняемых файлов клиента файл конфигурации приложения находится в том же каталоге, что и исполняемый файл приложения и имеет то же базовое имя, что и исполняемый файл с расширением .config. Например, файл конфигурации для C:\Program Files\Myapp\Myapp.exe является C:\Program Files\Myapp\Myapp.exe.config. В сценарии на основе браузера HTML-файл должен использовать <элемент ссылки>, чтобы явно указать файл конфигурации.

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

<configuration>
   <system.diagnostics>
      <trace useGlobalLock="false" autoflush="true" indentsize="0">
         <listeners>
            <add name="myListener" type="System.Diagnostics.TextWriterTraceListener, system version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="c:\myListener.log" />
         </listeners>
      </trace>
   </system.diagnostics>
</configuration>

Файл политики издателя

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

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

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

            <dependentAssembly>
                <assemblyIdentity name="asm6" publicKeyToken="c0305c36380ba429" />
                <bindingRedirect oldVersion="3.0.0.0" newVersion="2.0.0.0"/>
            </dependentAssembly>

        </assemblyBinding>
    </runtime>
</configuration>

Чтобы создать сборку, можно использовать средство Al.exe (компоновщик сборок) с помощью следующей команды:

Al.exe /link:asm6.exe.config /out:policy.3.0.asm6.dll /keyfile: compatkey.dat /v:3.0.0.0

compatkey.dat — это файл ключа строгого имени. Эта команда создает сборку с сильным именем, которую можно разместить в глобальном кэше сборок.

Замечание

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

Файл конфигурации политики издателя переопределяет сведения о версии, поступающие из приложения (т. е. из манифеста сборки или из файла конфигурации приложения). Если в файле конфигурации приложения нет инструкции для перенаправления версии, указанной в манифесте сборки, файл политики издателя переопределяет версию, указанную в манифесте сборки. Однако если в файле конфигурации приложения есть инструкция перенаправления, политика издателя переопределяет именно эту версию, а не ту, которая указана в манифесте.

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

Безопасный режим

Файлы политики издателя обычно устанавливаются явным образом в рамках пакета обновления или обновления программы. Если возникла проблема с обновленным общим компонентом, можно игнорировать переопределения в файле политики издателя с помощью безопасного режима. Безопасный режим определяется элементом <publisherPolicy применить="да|нет"/>, расположенным только в файле конфигурации приложения. Он указывает, следует ли удалять сведения о конфигурации политики издателя из процесса привязки.

Безопасный режим можно задать для всего приложения или для выбранных сборок. То есть вы можете отключить политику для всех сборок, составляющих приложение, или включить ее для некоторых сборок, но не для других. Чтобы выборочно применить политику издателя к сборкам, составляющим приложение, задайте <publisherPolicy apply=no/> и укажите, какие сборки необходимо затронуть, с помощью элемента <зависимыхAssembly>. Чтобы применить политику издателя ко всем сборкам, составляющим приложение, задайте <publisherPolicy apply=no/> без зависимых элементов сборки. Дополнительные сведения о конфигурации см. в разделе "Настройка приложений с помощью файлов конфигурации".

Файл конфигурации компьютера

В-третьих, среда выполнения проверяет файл конфигурации компьютера. Этот файл, называемый Machine.config, находится на локальном компьютере в подкаталоге конфигурации корневого каталога, где установлена среда выполнения. Этот файл можно использовать администраторами для указания ограничений привязки сборки, которые являются локальными для этого компьютера. Параметры в файле конфигурации компьютера имеют приоритет над всеми другими параметрами конфигурации; Однако это не означает, что все параметры конфигурации должны быть помещены в этот файл. Версия, определяемая файлом политики администратора, является окончательной и не может быть переопределена. Переопределения, указанные в файле Machine.config, влияют на все приложения. Дополнительные сведения о файлах конфигурации см. в разделе "Настройка приложений с помощью файлов конфигурации".

Шаг 2. Проверка ранее упоминавшихся сборок

Если запрошенная сборка также была запрошена в предыдущих вызовах, среда CLR использует сборку, которая уже загружена. Это может иметь последствия при именовании сборок, составляющих приложение. Дополнительные сведения об именовании сборок см. в разделе "Имена сборок".

Если предыдущий запрос сборки завершился сбоем, последующие запросы на сборку немедленно завершаются ошибкой, не пытаясь загрузить сборку. Начиная с .NET Framework версии 2.0 ошибки привязки сборок кэшируются, а кэшированные сведения используются для определения того, следует ли загружать сборку.

Замечание

Чтобы вернуться к поведению .NET Framework версий 1.0 и 1.1, которые не кэшировали сбои привязки, включите <элемент disableCachingBindingFailures> в файл конфигурации.

Шаг 3. Проверка глобального кэша сборок

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

Шаг 4. Поиск сборки с помощью баз кода или проверки

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

  1. <Если элемент codeBase> найден в файле конфигурации приложения, среда выполнения проверяет указанное расположение. При обнаружении совпадения используется эта сборка и не выполняется проверка. Если сборка не найдена, запрос привязки завершается ошибкой.

  2. Затем среда выполнения проверяет наличие указанной на ссылке сборки с помощью правил, указанных далее в этом разделе.

Замечание

Если в каталоге есть несколько версий сборки, и вы хотите ссылаться на определенную версию этой сборки, необходимо использовать <элемент codeBase> вместо privatePath атрибута <элемента проверки> . Если вы используете <элемент проверки,> среда выполнения останавливает проверку при первом поиске сборки, соответствующей простому имени сборки, на которую ссылается ссылка, независимо от того, соответствует ли она правильному совпадению. Если совпадение правильное, используется данная сборка. Если это несоответствие, процесс проверки останавливается и привязка не удаётся.

Поиск сборки через кодовые базы

Сведения о базе кода можно предоставить с помощью <элемента CodeBase> в файле конфигурации. Эта база кода всегда проверяется перед тем, как среда выполнения пытается проверить наличие указанной сборки. Если файл политики издателя, содержащий перенаправление последней версии, также содержит элемент <codeBase>, используется именно этот элемент <codeBase>. Например, если файл конфигурации приложения задает <элемент codeBase>, а файл политики издателя, переопределяющий сведения о приложении, также указывает <элемент codeBase, используется элемент codeBase><в файле политики издателя.>

Если совпадение не найдено в расположении, указанном элементом <codeBase> , запрос привязки завершается ошибкой, и дальнейшие действия не выполняются. Если среда выполнения определяет, что сборка соответствует критериям вызывающей сборки, используется эта сборка. Когда загружается файл, указанный элементом <codeBase>, среда выполнения проверяет, соответствуют ли имя, версия, культура, региональные параметры и открытый ключ ссылке вызывающей сборки.

Замечание

Сборки, на которые ссылаются, и которые находятся за пределами корневого каталога приложения, должны иметь строгие имена и быть установлены в глобальный кэш сборок или быть указаны с помощью элемента <codeBase>.

Поиск сборки с помощью зондирования

Если в файле конфигурации приложения отсутствует <элемент CodeBase> , среда выполнения проверяет сборку с помощью четырех условий:

  • Базовый каталог приложения, где выполняется его запуск.

  • Атрибут культуры, на который ссылается сборка.

  • Имя, которое является именем указанной сборки.

  • Атрибут privatePath элемента <probing>, представляющий собой список подкаталогов, определяемый пользователем, в расположении корневого каталога. Это расположение можно указать в файле конфигурации приложения и в управляемом коде с помощью AppDomainSetup.PrivateBinPath свойства для домена приложения. При указании в управляемом коде сначала проверяется управляемый код privatePath , а затем путь, указанный в файле конфигурации приложения.

Проверка каталогов базы приложений и культурных настроек

Среда выполнения всегда начинает проверку в базе приложения, которая может быть URL-адресом или корневым каталогом приложения на компьютере. Если указанная сборка не найдена в базовом каталоге приложения и информация о культуре отсутствует, среда выполнения выполняет поиск во всех подкаталогах с именем сборки. Каталоги, которые проверялись, включают:

  • [база приложения] / [имя сборки].dll

  • [база приложения] / [имя сборки] / [имя сборки].dll

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

  • [база приложений] / [культура] / [имя сборки].dll

  • [основа приложения] / [культура] / [имя сборки] / [имя сборки].dll

Проверка с помощью атрибута privatePath

Помимо подкаталогов культуры и подкаталогов, именованных в соответствии с указанной сборкой, среда выполнения также осуществляет поиск в каталогах, указанных с помощью атрибута privatePath элемента <probing>. Каталоги, указанные с помощью атрибута privatePath , должны быть подкаталогами корневого каталога приложения. Проверяемые каталоги зависят от того, включена ли информация о языке и региональных параметрах в запрос сборки со ссылкой.

Среда выполнения останавливает проверку при первом поиске сборки, которая соответствует простому имени сборки, на которую ссылается ссылка, независимо от того, соответствует ли она правильному совпадению. Если совпадение правильное, используется данная сборка. Если это несоответствие, процесс проверки останавливается и привязка не удаётся.

Если включена культура, проверяются следующие каталоги:

  • [база приложений] / [binpath] / [culture] / [имя сборки].dll

  • [база приложений] / [binpath] / [culture] / [имя сборки] / [имя сборки].dll

Если информация о культуре не включена, пробуются следующие каталоги.

  • [база приложения] / [binpath] / [имя сборки].dll

  • [база приложений] / [binpath] / [имя сборки] / [имя сборки].dll

Примеры проверки

Учитывая следующие сведения:

  • Имя сборки со ссылкой: myAssembly

  • Корневой каталог приложения: http://www.code.microsoft.com

  • <Элемент зондирования> в файле конфигурации указывает: bin

  • Культура: de

Среда выполнения проверяет следующие URL-адреса:

  • http://www.code.microsoft.com/de/myAssembly.dll

  • http://www.code.microsoft.com/de/myAssembly/myAssembly.dll

  • http://www.code.microsoft.com/bin/de/myAssembly.dll

  • http://www.code.microsoft.com/bin/de/myAssembly/myAssembly.dll

Несколько сборок с одинаковым именем

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

<dependentAssembly>
   <assemblyIdentity name="Server" publicKeyToken="c0305c36380ba429" />
   <codeBase version="1.0.0.0" href="v1/Server.dll" />
   <codeBase version="2.0.0.0" href="v2/Server.dll" />
</dependentAssembly>

Другие места исследованы

Расположение сборки также можно определить с помощью текущего контекста привязки. Это чаще всего происходит в сценариях взаимодействия COM и при использовании метода Assembly.LoadFrom. Если сборка использует LoadFrom метод для ссылки на другую сборку, то расположение вызываемой сборки считается указанием о том, где найти указанную сборку. Если найдено совпадение, сборка загружается. Если совпадение не найдено, среда выполнения продолжает поиск в соответствии с его семантикой, а затем запрашивает установщик Windows для предоставления сборки. Если не предоставлена сборка, соответствующая запросу привязки, выбрасывается исключение. Это исключение является TypeLoadException в управляемом коде, если обращение было к типу, или FileNotFoundException, если загружаемая сборка не была найдена.

Например, если Assembly1 ссылается на Assembly2 и Assembly1 была загружена из http://www.code.microsoft.com/utils, то это расположение считается подсказкой о том, где найти Assembly2.dll. Затем среда выполнения пробует найти сборку в http://www.code.microsoft.com/utils/Assembly2.dll и в http://www.code.microsoft.com/utils/Assembly2/Assembly2.dll. Если Assembly2 не найдена ни в одном из этих расположений, runtime запрашивает установщик Windows.

См. также