Зависимая DLL не копируется в папку вывода сборки в Visual Studio

У меня есть визуальное студийное решение. У меня много проектов в решении. Существует один основной проект, который действует как запуск и использует другие проекты. Один проект говорит "ProjectX". Его ссылка добавлена ​​к основному проекту. ProjectX ссылается на другую .NET dll (скажем, abc.dll), которая не является частью решения.

Теперь этот файл abc.dll следует скопировать в папку bin/debug основного проекта, но он не копируется там. Почему он не копируется, какие-либо известные причины?

Ответ 1

Я обнаружил, что если ProjectX ссылается на abc.dll, но напрямую не использует какой-либо тип DEFINED в abc.dll, то abc.dll НЕ будет скопирован в основную папку вывода. (Он будет скопирован в выходную папку ProjectX, чтобы сделать его чересчур запутанным.)

Итак, если вы явно не используете какие-либо типы из abc.dll в любом месте ProjectX, тогда помещайте фиктивную декларацию где-нибудь в один из файлов ProjectX.

AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied

Вам не нужно делать это для каждого класса - только один раз будет достаточно, чтобы сделать копию DLL, и все работает должным образом.

Добавление: Обратите внимание, что это может работать в режиме отладки, но НЕ для выпуска. Подробнее см. В описании @nvirth.

Ответ 2

Просто ответ на вопрос Оверлорда Цурга.

Я добавил фиктивную ссылку таким образом, и она работала в режиме отладки:

public class DummyClass
{
    private static void Dummy()
    {
        var dummy = typeof(AbcDll.AnyClass);
    }
}

Но в режиме Release зависимая dll все равно не копируется.

Однако это сработало:

public class DummyClass
{
    private static void Dummy()
    {
        Action<Type> noop = _ => {};
        var dummy = typeof(AbcDll.AnyClass);
        noop(dummy);
    }
}

Эта информация действительно стоила мне часов, чтобы понять, поэтому я решил поделиться ею.

Ответ 3

Да, вам нужно установить Copy Local в true. Тем не менее, я уверен, что вам также понадобится ссылаться на эту сборку из основного проекта и установить Copy Local на true, а также - он не просто копируется из зависимой сборки.

Вы можете перейти в свойство Copy Local, щелкнув узел под References и нажав F4.

Ответ 4

Он выглядит скользким, когда вы делаете его атрибутом сборки

[AttributeUsage(AttributeTargets.Assembly)]
public class ForceAssemblyReference: Attribute
{        
    public ForceAssemblyReference(Type forcedType)
    {
        //not sure if these two lines are required since 
        //the type is passed to constructor as parameter, 
        //thus effectively being used
        Action<Type> noop = _ => { };
        noop(forcedType);
    }
}

Использование будет:

[assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]

Ответ 5

В этой же проблеме. Фоновая информация: до создания я добавил новый проект X в решение. Проект Y зависит от проекта X, а проект A, B, C зависит от проекта Y.

Ошибки сборки заключались в том, что не удалось найти файлы проекта A, B, C, Y и X.

Основной причиной было то, что только что созданный Project X нацелился на .NET 4.5, а остальные проекты решений нацелены на .NET 4.5.1. Проект X не создавал, заставляя остальные проекты не создайте также.

Убедитесь, что все вновь добавленные проекты нацелены на одну и ту же версию .NET, как и на оставшуюся часть решения.

Ответ 6

Не уверен, что это помогает, но для меня много раз я ссылаюсь на DLL (который автоматически добавляет его в папку bin, конечно). Однако для этой DLL могут потребоваться дополнительные библиотеки DLL (в зависимости от того, какие функции я использую). Я НЕ хочу ссылаться на тех, что находятся в моем проекте, потому что просто нужно просто оказаться в той же папке, что и я, использую DLL.

Я выполняю это в Visual Studio с помощью "Добавление существующего файла". Вы можете добавить его куда угодно, кроме папки Add_data. лично я просто добавляю его в корень.

Затем измените свойства этого файла на...

Build Action = None (с этим набором на что-то вроде Content фактически копирует "корневую" версию в корневой каталог, а также копию в Bin).

Скопировать в папку вывода = Копировать, если новый (в основном помещается в папку BIN, только если он отсутствует, но не делает этого после этого)

Когда я публикую.. моя добавленная DLL существует только в папке BIN и нигде в месте публикации (это то, что я хочу).

Ответ 7

Вы также можете проверить, не находятся ли вы в DLL, которые вы ищете, в GAC. Я считаю, что Visual Studio умеет не копировать эти файлы, если он уже существует в GAC на машине сборки.

Недавно я столкнулся с этой ситуацией, когда я тестировал пакет SSIS, который требовал сборки в GAC. С тех пор я забыл об этом и задавался вопросом, почему эти DLL не выходили во время сборки.

Чтобы проверить, что в GAC (из командной строки разработчика Visual Studio):

gacutil -l

Или вывод в файл, чтобы его было легче читать:

gacutil -l > output.txt
notepad.exe output.txt

Чтобы удалить сборку:

gacutil -u MyProjectAssemblyName

Следует также отметить, что после того, как я удалил файлы из GAC, они были правильно выведены в каталог \bin после сборки (даже для сборок, которые не были напрямую указаны в корневом проекте). Это было в Visual Studio 2013 Update 5.

Ответ 8

Это небольшая настройка на примере nvirth

internal class DummyClass
{
    private static void Dummy()
    {
        Noop(typeof(AbcDll.AnyClass));
    }
    private static void Noop(Type _) { }
}

Ответ 9

В моем случае это была самая глупая вещь, вызванная поведением TFS/VS по умолчанию, с которым я не согласен.

Поскольку добавление DLL в качестве ссылки на основной проект не сработало, я решил добавить его как "Существующий элемент", с копией Local = Always. Даже тогда файла не было.

Оказывается, несмотря на то, что файл присутствует в VS Solution и все скомпилировано как локально, так и на сервере, VS/TFS не добавляет, фактически добавляет файл в исходный элемент управления. Он не был включен в "Ожидающие изменения" вообще. Мне пришлось вручную перейти в Source Control Explorer и явно нажать значок "Добавить элементы в папку".

Глупо, потому что я развиваюсь 15 лет в VS. Я сталкивался с этим раньше, я просто не помнил, и почему-то я его пропустил, потому что все еще было скомпилировано из-за того, что файл был регулярной ссылкой, но файл, который был добавлен как "Существующий элемент", не копировался, потому что его не было на сервер управления версиями.

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

Ответ 10

Если вы правы Щелкните ссылку, на которую ссылается сборка, вы увидите свойство Copy Local. Если для параметра "Копировать местность" установлено значение "Истина", сборка должна быть включена в корзину. Тем не менее, существует шов, который может быть проблемой с Visual Studio, что иногда он не содержит ссылочную DLL в папке bin... это обходной путь, который работал для меня:

enter image description here

Ответ 11

Я бы добавил его к событиям Postbuild, чтобы скопировать необходимые библиотеки в выходные каталоги. Что-то вроде XCopy pathtolibraries targetdirectory

Вы можете найти их в свойствах проекта → Build Events.

Ответ 12

Вы можете установить выходной путь основного проекта и ProjectX в одну и ту же папку, тогда вы можете получить все необходимые вам библиотеки в этой папке.

Ответ 13

Убедитесь, что зависимая dll, используемая вами, не имеет целевой .net-структуры выше целевой .net-структуры вашего проекта.

Вы можете проверить это, выбрав свой проект, затем нажмите ALT + ENTER, затем выберите приложение с левой стороны, а затем выберите Target Framework вашего проекта.

Предположим, зависимая dll Target Framework = 4.0 и  Приложение dll Target Framework = 3.5, затем измените это на 4.0

Спасибо!

Ответ 14

Помимо общих выше, у меня было многопроектное решение для публикации. По-видимому, некоторые файлы предназначены для разных фреймворков.

Итак, мое решение: Свойствa > Конкретная версия (False)

Ответ 15

НЕТ НЕОБХОДИМОСТИ ДЛЯ ДАММИ В КОДЕ
Просто:

добавить ссылку на проект Executeable

или/и убедитесь, что ссылка в исполняемом проекте "Copy Local" установлена ​​на TRUE (которая была моей "ошибкой" ), кажется, что эта "перезапись" параметра в базовом справочном библиотечном проекте...

Ответ 16

Добавьте DLL в качестве существующего элемента в один из проектов и его нужно отсортировать

Ответ 17

Вопрос:

Обнаружена похожая проблема для библиотеки DLL пакета NuGet (Newtonsoft.json.dll), в которой выходные данные сборки не содержат ссылочную библиотеку DLL. Но компиляция идет хорошо.

Исправление:

Просматривайте свои проекты в текстовом редакторе и ищите ссылки с тегами в них. Как Истина или Ложь. "Private" - это синоним "Copy Local". Где-то в действиях MSBuild пытается найти зависимости, найти свою зависимость где-то еще и принять решение не копировать ее.

Итак, просмотрите каждый файл .csproj/.vbproj и удалите теги вручную. Перестройте, и все работает как в Visual Studio, так и в MSBuild. Получив эту работу, вы можете вернуться и обновить ее там, где, по вашему мнению, они должны быть.

Ссылка:

https://www.paraesthesia.com/archive/2008/02/13/what-to-do-if-copy-local-works-in-vs-but.aspx/