MSBuild не копирует ссылки (файлы DLL), если использует зависимости проекта в решении - PullRequest
263 голосов
/ 15 июля 2009

У меня есть четыре проекта в моем решении Visual Studio (все ориентированы на .NET 3.5) - для моей проблемы важны только эти два:

  1. MyBaseProject <- эта библиотека классов ссылается на сторонний DLL-файл (elmah.dll) </li>
  2. MyWebProject1 <- этот проект веб-приложения имеет ссылку на MyBaseProject </li>

Я добавил ссылку elmah.dll на MyBaseProject в Visual studio 2008, нажав «Добавить ссылку ...» → вкладку «Обзор» → выбрав «elmah.dll».

Свойства ссылки на Эльму следующие:

  • Псевдонимы - глобальные
  • Копировать локально - true
  • Культура -
  • Описание - Модули и обработчики ошибок (ELMAH) для ASP.NET
  • Тип файла - Сборка
  • Путь - D: \ webs \ otherfolder \ _myPath \ __ tools \ elmah \ Elmah.dll
  • Решено - Верно
  • Runtime версия - v2.0.50727
  • Указанная версия - false
  • Сильное имя - ложь
  • Версия - 1.0.11211.0

В MyWebProject1 Я добавил ссылку на проект MyBaseProject: «Добавить ссылку ...» → вкладка «Проекты» → выбрать «MyBaseProject». Свойства этой ссылки те же, за исключением следующих элементов:

  • Описание -
  • Путь - D: \ webs \ CMS \ MyBaseProject \ bin \ Debug \ MyBaseProject.dll
  • Версия - 1.0.0.0

Если я запускаю сборку в Visual Studio , файл elmah.dll копируется в мою папку bin MyWebProject1 вместе с MyBaseProject.dll!

Однако, если я очищаю и запускаю MSBuild для решения (через D: \ webs \ CMS> C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe / t: ReBuild / p: Configuration = Debug MyProject.sln) elmah.dll отсутствует в каталоге bin MyWebProject1 - хотя сама сборка не содержит предупреждений или ошибок!

Я уже убедился, что .csproj MyBaseProject содержит элемент private со значением "true" (это должен быть псевдоним для " copy local " в Visual Studio) :

<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\mypath\__tools\elmah\Elmah.dll</HintPath>
    **<Private>true</Private>**
</Reference>

(Закрытый тег не появился в XML-файле .csproj по умолчанию, хотя Visual Studio сказала «копировать локальный» в значение true. Я переключил «копировать локальный» в значение «ложь» - сохранено - и снова установило значение «истина» - сохранить! )

Что не так с MSBuild? Как получить ссылку (elmah.dll), скопированную в корзину MyWebProject1?

Я НЕ хочу добавлять действие копирования после сборки в команду каждого проекта после сборки! (Представьте, что многие проекты зависят от MyBaseProject!)

Ответы [ 18 ]

2 голосов
/ 26 ноября 2013

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

Некоторые примеры можно найти в другом посте

2 голосов
/ 27 июня 2012

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

2 голосов
/ 02 октября 2013

Для этого необходимо добавить файл .targets в проект и настроить его для включения в раздел включений проекта.

См. мой ответ здесь для процедуры.

2 голосов
/ 20 марта 2017

Другой сценарий, в котором это проявляется, - это если вы используете старый тип проекта «Веб-сайт» в Visual Studio. Для этого типа проекта он не может ссылаться на .dll, которые находятся за пределами его собственной структуры каталогов (текущей папки и вниз). Итак, в ответе выше, скажем, ваша структура каталогов выглядит следующим образом:

enter image description here

Где ProjectX и ProjectY являются родительскими / дочерними каталогами, а ProjectX ссылается на A.dll, которая, в свою очередь, ссылается на B.dll, а B.dll находится вне структуры каталогов, например, в пакете Nuget в корне (Packages) тогда A.dll будет включен, но B.dll не будет.

0 голосов
/ 08 февраля 2019

Убедитесь, что оба проекта находятся в одной и той же версии .net, также проверьте копию локального свойства, но это должно быть true по умолчанию

0 голосов
/ 19 марта 2016

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

У меня есть приложение ASP.NET. Процесс сборки настроен на очистку, а затем сборка.

У меня есть два Jenkins CI сценария. Один для производства и один для постановки. Я развернул свое приложение для постановки, и все работало нормально. Развернут в производство и отсутствует файл DLL, на который есть ссылка. Этот файл DLL был только в корне проекта. Не в любом хранилище NuGet. DLL была установлена ​​на do not copy.

Скрипт CI и приложение были одинаковыми между двумя развертываниями. После очистки и развертывания в промежуточной среде файл DLL был заменен в месте развертывания приложения ASP.NET (bin/). Это не относится к производственной среде.

Оказывается, в ветке тестирования я добавил шаг к процессу сборки, чтобы скопировать этот DLL-файл в каталог bin. Теперь часть, которая заняла некоторое время, чтобы выяснить. Процесс CI не очищался сам по себе. DLL была оставлена ​​в рабочем каталоге и была случайно упакована с файлом .zip ASP.NET. Производственная ветка никогда не копировала DLL-файл таким же образом и никогда не развертывала это случайно.

TLDR; Проверьте и убедитесь, что вы знаете, что делает ваш сервер сборки.

0 голосов
/ 16 августа 2012

Я только что столкнулся с очень похожей проблемой. При компиляции с использованием Visual Studio 2010 файл DLL был включен в папку bin. Но при компиляции с использованием MSBuild сторонний DLL-файл не был включен.

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

0 голосов
/ 04 декабря 2013

Включение всех ссылочных DLL-файлов из ваших проектных ссылок в проект Website - не всегда хорошая идея, особенно когда вы используете внедрение зависимостей : ваш веб-проект просто хочет добавить ссылку на интерфейс DLL файл / проект, а не какой-либо конкретный файл реализации DLL.

Потому что, если вы добавите ссылку непосредственно в файл / проект реализации DLL, вы не сможете запретить вашему разработчику вызывать «новый» для конкретных классов файла / проекта реализации DLL вместо использования интерфейса. Вы также указали на своем веб-сайте «жесткий код», чтобы использовать реализацию.

...