2013-02-17 2 views
4

Вот мой пример сценария. У меня есть консольное приложение и DLL библиотеки классов (назовите его libraryA). DLL LibraryA ссылается на Oracle.DataAccess.dll версии 4.112.2.0. Oracle DLL находится в GAC. Ссылка на DLL Oracle в LibraryA - «Копировать локально = ложь». Все идет нормально. Если вы создаете библиотеку dll библиотеки, то в ее выходном каталоге появляется файл Oracle.DataAccess.dll , а не. ОК. Теперь я ссылаюсь на библиотеку dll в моем консольном приложении. Ссылка на библиотеку dll - «copy local = true». Теперь, когда я создаю консольное приложение, Oracle.DataAcess.dll делает в выходном каталоге для консольного приложения. Однако, похоже, что единственная DLL, которая действует таким образом, - это dll Oracle. Вот полный код из LibraryAСборка скопирована локально, если она не должна быть

public void Foo() {    
    Oracle.DataAccess.Client.OracleConnection c = new Oracle.DataAccess.Client.OracleConnection(); 
    WebMatrix.WebData.OAuthAccountData x = new WebMatrix.WebData.OAuthAccountData("asd", "asd");    
    DevExpress.Web.ASPxCallback.ASPxCallback cvv = new DevExpress.Web.ASPxCallback.ASPxCallback(); 
} 

WebMatrix и DevExpress также в GAC так же, как в Oracle DLL. Однако ни одна из этих DLL не выводится в выходной каталог, а только в dll Oracle. Почему? Что тут происходит?

В этом случае вы можете создать другую библиотеку классов, назовите ее libraryB, НЕ помещайте библиотеку B в GAC, ссылку LibraryB из LibraryA и скопируйте local = false. Даже когда вы это делаете, libraryB не копируется в выходной каталог консольного приложения. Конечно, в этом случае программа взрывается, потому что она не может найти библиотеку B, но по крайней мере Visual Studio уважает локальный флаг copy = false. Чем отличается эта глупая DLL Oracle?

О, еще одна вещь, это смешно. Если в моем консольном приложении I явно, добавьте ссылку на Oracle.DataAccess.dll и скажите copy local = false, , затем он не отображается в выходном каталоге. Кажется, вроде весел, что не есть DLL отображаются в выходном каталоге, у меня есть на самом деле ссылка это :)

Edit:

Еще один ключ. Oracle, чтобы пытать разработчиков, не имеет одной DLL, построенной для AnyCPU. Они имеют x86 и x64 версию. В моем случае я ссылаюсь на версию x86 и строю для AnyCPU. Однако, если я создаю для x86 (для соответствия dll oracle), то DLL Oracle составляет , а не, скопированный в выходной каталог. при создании в AnyCPU MSBUILD говорит: «Предупреждение MSB3270: произошла несоответствие между архитектурой процессора создаваемого проекта« MSIL »и процессорной архитектурой справки« Oracle.DataAccess, Version = 4.112.2.0, Culture = neutral , PublicKeyToken = 89b483f429c47342, processorArchitecture = x86 "," x86 ". Это несоответствие может привести к сбоям во время выполнения. Пожалуйста, подумайте об изменении целевой архитектуры процессора вашего проекта через Configuration Manager, чтобы согласовать архитектуры процессоров между вашим проектом и ссылками или принять зависимость от ссылок на архитектуру процессора, которая соответствует целевой архитектуре процессора вашего проекта ». Итак, почти похоже, что Msbuild в конечном итоге решила, что, хорошо, у вас есть несоответствие, поэтому позвольте мне продолжить и скопировать эту dll в ваш выходной каталог, таким образом гарантирует, что ваше приложение взорвется. :)

+0

Я имею дело с такой же нечетной проблемой с Oracle.DataAccess.dll, и получаю то же предупреждение в своем выпуске. Я думаю, мне придется добавить ссылку на Oracle.DataAccess.dll во всех моих проектах ... –

+0

@aquinas, вы когда-нибудь пришли к дальнейшему решению этой проблемы? Я испытываю то, что звучит как одна и та же проблема с другой сторонней DLL (сопоставление симптомов вплоть до нескольких типов процессоров), и я почти разорвал свои волосы. –

+0

В нашем случае мы подтвердили, что эта проблема не воспроизводится на машинах, на которых не установлен .NET 4.5, но когда кто-то устанавливает 4.5, проблема начинается. Мы работаем над определением того, как .NET 4.5 запускает это поведение. –

ответ

4

Не ссылаясь на это, вы разрешаете использовать неявные правила. Ну, неявное значение по умолчанию здесь «скопируйте его локально», потому что большинство dlls не находятся в GAC. У IDE есть сумасшедшее понятие о том, чтобы «заставить работать», что означает «предположим, что он не будет в GAC».

Если вы хотите использовать явные правила, тогда да: вам нужно сказать, что вы хотите. И как вы это делаете, добавив ссылку, а затем установив нужные параметры.

+0

Хорошо, но почему другие DLL-файлы, с которыми я ссылаюсь, работают не так? Кроме того, IDE * не * пытается заставить его работать с DLL, которая не находится в GAC. Например, если я ссылаюсь на библиотеку B из библиотеки A и не имею копию local = false, библиотека B не копируется. Почему эта оракула (и только эта оракула) DLL? – aquinas

+1

@ aquinas это зависит от нескольких вещей: вы ссылаетесь на него напрямую? или косвенно? это в GAC на локальной машине? или нет? в частности, когда-то (и все еще может быть) тонкая ошибка IDE, где copy-local на самом деле три-состояние: «true», «false» или «не указано явно значение» - это означает, что вы действительно можете получить разные результаты для «false»: если он «ложный» изначально, он может быть «ложным по умолчанию», который может вести себя по-разному с «явно ложным», так как «false по умолчанию» на самом деле является проверкой на GAC. –

+0

Я ссылаюсь на него непосредственно в LibraryA. Я ссылаюсь на LibraryA непосредственно из ConsoleApplication1. DLL находится в GAC на локальной машине при создании. Тем не менее, я попытался удалить его из GAC, и это не имело никакого значения. Опять же, это поведение ТОЛЬКО происходит с этой единственной dll. Попробуй. 1) Создайте консольное приложение. 2) создайте библиотеку. 3) Обратитесь в свою библиотеку и скопируйте local = true. 4) укажите ЛЮБОЙ dll в GAC из вашей библиотеки и установите copy local = false. 5) Создайте экземпляр класса из dll GACed.DLL GACed не будет скопирована в выходной каталог. – aquinas

0

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

Хотя ранее мы не видели такой ошибки в журнале сборки, на затронутых машинах теперь мы видим сообщение о том, что проекты строятся для MSIL, а DLL построена для x86 - вместо того, чтобы создавать одну DLL-встроенную для всех процессоров сторонний создатель предоставляет две отдельные библиотеки DLL для x86 и x64, обе из которых находятся в нашем GAC. Перед вводом этой проверки система будет использовать DLL из GAC и выбрать соответствующую версию, но, похоже, что после установки .NET 4.5 процесс сборки определяет, что ни одна из версий в GAC не является приемлемой, поэтому она вытягивает локальная копия.

Мы не смогли идентифицировать какой-либо способ отключить это поведение, поэтому наши параметры разрешения должны быть либо просто добавлены после сборки, чтобы удалить локальные копии, либо (как упоминалось в вопросе), чтобы добавить ссылки на DLL проблемы ко всем проектам, которые ссылаются на нашу «Библиотеку А», а затем установить эти ссылки на «copy local = false», что также предотвращает копирование неработающей локальной версии в выходной файл.

Смежные вопросы