Как среда выполнения разрешает вызовы сборок .NET 2.0 SP1, если присутствует только .NET 2.0 RTM - PullRequest
3 голосов
/ 21 марта 2011

У нас есть приложение, созданное для .NET 2.0 на компьютере с установленным .NET 2.0 SP1. Приложение ссылается на некоторые стандартные сборки .NET, включенные в .NET SP1 (т.е. System.Xml.dll).

Если мы запустим это приложение на компьютере с .net 2.0 RTM, приложение будет работать нормально, оно даже использует System.Xml.dll сборку. Но когда он пытается использовать метод, который не существует в 2.0 RTM, но существует в 2.0 SP1, приложение выдает MethodNotFoundException .

Мой вопрос: Как среда выполнения разрешает System.Xml.dll вообще?

Версии сборок отличаются по номеру ревизии (но основная, вспомогательная и сборочная части равны). Это означает, что сборки 2.0 RTM и 2.0 SP1 отличаются с точки зрения процесса привязки сборки. Среда выполнения должна попытаться найти System.Xml.dll 2.0.50727.1378, но находит только 2.0.50727.42. Тогда процесс привязки сборки должен завершиться сбоем, поскольку в Machine.config не может быть никакой политики или перенаправления Publisher. Но переплет работает отлично. Как это может быть?

Еще один вопрос, который следует за проблемой, описанной выше.

Мы не можем заставить всех наших клиентов установить .NET 2.0 SP1 на свои компьютеры. Если мы отправляем System.Xml.dll из .NET 2.0 SP1, как мы можем заставить наше приложение использовать System.Xml.dll, поставляемое с нашим приложением?

Обновление 1: Похоже, что System.Xml.dll версия 2.0.0.0, а не 2.0.50727.x. Это объясняет, почему среда выполнения успешно разрешает его. Но второй вопрос остается в силе: можем ли мы отправить System.Xml.dll из пакета обновления 1 вместе с нашим приложением и заставить наше приложение его использовать?

Ответы [ 2 ]

1 голос
/ 12 апреля 2011

Если нет приемлемых ответов, я выложу свои. Надеюсь, это кому-нибудь поможет.

Первый вопрос заключался в том, как среда выполнения разрешает сборки из пакета обновления.

Я немного больше исследовал и прочитал несколько статей. Я по ошибке посмотрел на AssemblyFileVersion вместо AssemblyVersion. Для сборок в .NET 2.0 SP AssemblyFileVersion это 2.0.50727.1378, а для сборок из .NET 2.0 RTM это 2.0.50727.42. Да, они разные, но это AssemblyFileVersion, а не AssemblyVersion. И процесс привязки сборки использует только AssemblyVersion. Но AssemblyVersion равно 2.0.0.0 для .NET 2.0 RTM и .NET SPx либо. Таким образом, сборки RTM и SPx идентичны с точки зрения процесса привязки сборки.

Мне все еще интересно, почему MS не поставляла сборки пакета обновления с увеличенным AssemblyVersion? Они могут отправлять сборки SP's с соответствующими политиками Publisher, чтобы перенаправить привязку сборки с RTM на SP. И если клиенты хотят использовать RTM версии сборок, они могут игнорировать политику издателя для определенных сборок. На самом деле, я думаю, что MS отказалась пойти по этому пути, потому что было бы полным беспорядком, если бы клиент начал игнорировать политики издателей на некоторых сборках и не игнорировать на других. Если BCL's сборки не могут полагаться друг на друга, все BCL станет несовместимым.

Второй вопрос касался возможности отправки .NET 2.0 SP1 сборок с нашим продуктом и перенаправления привязки сборки с RTM сборки на SP's сборки.

Краткий ответ: «Нет, это невозможно». Но есть 2 возможных решения, но они довольно неудачны и могут быть полезны только при строгих обстоятельствах, и в целом они вообще не применимы.

Первое решение состоит в том, чтобы отключить сборку CLR и затем собрать ее заново, но с нашим открытым ключом, иначе мы можем вообще не использовать строгую подпись. Теперь мы сможем ссылаться на эту RTM сборку, а не на SP's сборку из GAC.

Второе решение - заменить сборку RTM's в GAC сборкой SP с помощью инструмента gacutil. Опция /f (сила) должна использоваться.

Оба эти решения очень хромые. Пожалуйста, не используйте их. Как правило, их нельзя использовать из-за некоторых зависимостей между сборками.

Заключение

В нашем продукте мы понизили наш продукт, чтобы он мог работать на .NET 2.0 RTM. Но мы все еще используем некоторые функции даже из .NET 3.x (linq-to-objects, Action, Func). Мы просто поставляем некоторые сборки 3.x вместе с нашим продуктом, например, System.Core.dll. В основном у нас нет проблем с этим подходом. Но нам также пришлось отказаться от использования Linq-to-Xml из-за некоторых неразрешимых проблем.

0 голосов
/ 21 марта 2011

.NET-версии применяются только для сборок со строгими именами.

Вы не можете (и не должны) ожидать, что программа будет работать правильно в RTM-версии, когда она скомпилирована с использованием SP1. Он может работать правильно, но может и не работать таинственным образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...