2013-09-05 11 views
1

В настоящее время я работаю над получением .NET Assemblies (с COM-классами) для бесплатной регистрации работы. Он работает хорошо, однако у меня есть одна проблема, и я не могу точно указать точную причину.Как SXS выбирает версию рамочной версии?

Моя проблема заключается в том, что привязка сборки не выполняется в правильной версии .NET Framework.

В настоящее время у меня есть 2 сборки (назовем их A.dll и B.dll), и они оба построены с использованием .NET 4.0.

B.dll очень маленький, я попробовал протестировать активацию без регистрации. У него есть манифест рядом с ним, B.dll.manifest). Он содержит 1 класс с 1 свойством и 1 методом.

A.dll намного сложнее, подписан, манифест встроен в качестве ресурса как событие после сборки (с использованием mt.exe).

Я применил приложение VB6 для их проверки. В моем приложении есть манифест, который объявляет зависимости.

Если я запустил приложение, B.dll работает хорошо, но A.dll этого не делает. Посмотрев на журналы привязки с fuslogvw.exe, я обнаружил, что привязка A.dll выполняется с использованием .NET 2.0, а B.dll - с использованием .NET 4.0.

A.dll заканчивается сбоем с кодом ошибки 0x8013101b, который является COR_E_NEWER_RUNTIME. ERR: Ошибка извлечения манифеста из файла (hr = 0x8013101b).

Чтобы заставить его работать, я должен добавить файл .config в моем VB6 приложения с этим содержанием

<?xml version="1.0"?> 
<configuration> 
    <startup useLegacyV2RuntimeActivationPolicy="true" > 
     <supportedRuntime version="v4.0" /> 
    </startup> 
</configuration> 

Затем он связывается с надлежащей рамочной версии, и она работает.

Я уверен, что, возможно, MT.exe изменил атрибуты/метаинформации в моей сборке, заставив его подумать, что он должен быть загружен с 2.0. Поэтому я открыл его с помощью ILSpy. Все, что я вижу там, говорит о 4.0, и ничего подозрительного.

Я читал, что сборка должна быть загружена по умолчанию с использованием FW, который использовался для сборки em (в моем случае они ВСЕ 4,0, не 2,0 в любом месте). Таким образом, я не получаю ПОЧЕМУ он пытается загрузить тот, который использует 2.0.

Это проблема для меня, так как я хотел бы избежать необходимости создавать/поддерживать, но больше всего DEPLOY тех .config для всех приложений, которые собираются использовать эту конкретную сборку. Это будет означать наличие около 100 файлов .config в моем конкретном случае.

Для справки:

MT.exe я использовал от 7.0a SDK и версии 5.2.3790.2076.

Описание: fuslogvw.Выход ехе (простите за французский и в перепутались подчеркнутыми полукокса, важной частью является основой номер версии в любом случае)

B, работая

JRN : cette liaison démarre dans le contexte de chargement de default. 
JRN : tentative de téléchargement du fichier de configuration de l'application à partir de file:///C:/RegFreeCom/BafComClient/binTB/Project1.exe.config. 
JRNÂ : Le fichier de configuration C:\RegFreeCom\BafComClient\binTB\Project1.exe.config n'existe pas. 
JRN : aucun fichier de configuration de l'application n'a été trouvé. 
JRN : utilisation du fichier de configuration d'hôte : 
JRN : utilisation du fichier de configuration de l'ordinateur à partir de C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config. 
JRN : stratégie non appliquée à la référence à ce stade (liaison d'assembly privée, personnalisée, partielle ou basée sur l'emplacement). 
JRN : tentative de téléchargement de la nouvelle URL file:///C:/RegFreeCom/BafComClient/binTB/sidebysidenet.DLL. 
JRN : le téléchargement de l'assembly a réussi. Tentative d'installation du fichier : C:\RegFreeCom\BafComClient\binTB\B.dll 
JRN : entrée dans la phase d'installation à exécution à partir de la source. 
JRN : le nom de l'assembly est : B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
JRN : la liaison a réussi. Elle retourne un assembly à partir de C:\RegFreeCom\BafComClient\binTB\B.dll. 
JRN : l'assembly est chargé dans le contexte de chargement default. 

А, не работает

JRN : cette liaison démarre dans le contexte de chargement de default. 
JRN : tentative de téléchargement du fichier de configuration de l'application à partir de file:///C:/RegFreeCom/BafComClient/binTB/Project1.exe.config. 
JRNÂ : Le fichier de configuration C:\RegFreeCom\BafComClient\binTB\Project1.exe.config n'existe pas. 
JRN : aucun fichier de configuration de l'application n'a été trouvé. 
JRN : utilisation du fichier de configuration de l'ordinateur à partir de C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config. 
JRN : référence post-stratégie : A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=SomeToken, processorArchitecture=MSIL 
JRN : échec de la recherche dans le GAC. 
JRN : tentative de téléchargement de la nouvelle URL file:///C:/RegFreeCom/BafComClient/binTB/A.DLL. 
JRN : le téléchargement de l'assembly a réussi. Tentative d'installation du fichier : C:\RegFreeCom\BafComClient\binTB\A.dll 
JRN : entrée dans la phase d'installation à exécution à partir de la source. 
ERR : erreur lors de l'extraction de l'importation du manifeste à partir du fichier (hr = 0x8013101b). 
ERR : impossible de terminer l'installation de l'assembly (hr = 0x8013101b). Détection terminée. 

A , работая (благодаря конфигурационному файлу)

JRN : cette liaison démarre dans le contexte de chargement de default. 
JRN : tentative de téléchargement du fichier de configuration de l'application à partir de file:///C:/RegFreeCom/BafComClient/binTB/Project1.exe.Config. 
JRN : le fichier de configuration de l'application a été trouvé (C:\RegFreeCom\BafComClient\binTB\Project1.exe.Config). 
JRN : utilisation du fichier de configuration de l'application : C:\RegFreeCom\BafComClient\binTB\Project1.exe.Config 
JRN : utilisation du fichier de configuration d'hôte : 
JRN : utilisation du fichier de configuration de l'ordinateur à partir de C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config. 
JRN : référence post-stratégie : A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=SomeToken, processorArchitecture=MSIL 
JRN : échec de la recherche dans le GAC. 
JRN : tentative de téléchargement de la nouvelle URL file:///C:/RegFreeCom/BafComClient/binTB/A.DLL. 
JRN : le téléchargement de l'assembly a réussi. Tentative d'installation du fichier : C:\RegFreeCom\BafComClient\binTB\A.dll 
JRN : entrée dans la phase d'installation à exécution à partir de la source. 
JRN : le nom de l'assembly est : A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=SomeToken 
JRN : la liaison a réussi. Elle retourne un assembly à partir de C:\RegFreeCom\BafComClient\binTB\A.dll. 
JRN : l'assembly est chargé dans le contexte de chargement default. 
+0

Думаю, что это из-за mt.exe, я изменил свое сообщение после сборки, чтобы генерировать манифест и пропускать вложение (оставив мою сборку нетронутой). Я все равно получаю ту же ошибку. Пробовал переходить к более новой версии MT (той, которая поставляется с SDK 8.1), и это тоже не исправило. –

+0

У меня были ссылки в моей сборке на более старые сборки 2.0. Я удалил их, чтобы проверить это. Тот же результат все же, поэтому ссылки не являются причиной моей проблемы. –

ответ

1

М. Миллер из команды CLR указал мне в правильном направлении. Мой манифест (сгенерированный mt.exe из Windows SDK 7.0A) не включал значение в runtimeVersion тега clrClass.

Это привело к тому, что загрузчик CLR попал в путь загрузки «Capped». Это ограничило путь загрузки, что, по словам М. Миллера, произошло, когда версия не v4 или выше, и она закрывает значение, возвращаемое загрузчиком «FindLatestVersion» на v2. Поэтому он пытается загрузить сборки с использованием 2.0 FW.

Изменение манифеста, чтобы указать правильную версию (v4.0.30319) и убедиться, что ничего не было кэшировано (мне пришлось копировать мою директорию где-то в другом месте, чтобы правильная версия отображалась в журналах), в конечном итоге решила мою проблему. Теперь загрузка идет по правильному пути, а не идет по пути «Capped».

Таким образом, это стало простой проблемой.

FWIW, я попытался создать тот же манифест, используя mt.exe из Windows SDK 8.1 (последний), и он сгенерировал атрибут runtimeVersion правильно!

Я хотел бы поблагодарить Марка Миллера за помощь в этом вопросе, без его помощи мне понадобилось время, чтобы понять это!

+0

О механизме кэширования я нашел эту запись в блоге. Кэширование делает отлаживание неисправного манифеста очень сложным. Эта запись в блоге содержит обходное решение http://csi-windows.com/blog/all/27-csi-news-general/245-find-out-why-your-external-manifest-is-being-ignored –

+1

Glad Я смог помочь. Ключевым моментом здесь было то, что для регистрации CLSID использовался reg-free COM, и манифест не включал строку версии, которую использует прокладка для определения того, какая среда исполнения является подходящей. Типичная регистрация в RegAsm или других инструментах создает ключи реестра с соответствующей строкой версии, и, видимо, mt.exe (по крайней мере, последний) получает это право. Обратите внимание, что это «версия времени исполнения», аналогичная версиям, используемым для элемента конфигурации поддерживаемого Runtime, а не «маркетинговые версии», используемые для .NET (3.5, 4.5 и т. Д.). –

+0

Да, последний (SDK 8.1) Выход mt.exe действительно содержит правильную версию runtimeVersion. Тем не менее, тот, который установлен под «7.0A», не работает. Просто предупреждение о том, что кто-то пытается использовать его для создания Reg-Free COM манифестаций. –