Visual Studio не копирует файлы содержимого из проекта с косвенной ссылкой

У меня есть следующая структура проекта:

Library1 <--[project reference]-- Library2 <--[ref]-- Executable
--------                          --------            ----------
ContentFile                      .cs files           .cs files
.cs files

Все ссылки на проекты имеют CopyLocal = true.

Когда я строю проект, ContentFile копируется в Library2 выходной каталог, но не Executable выходной каталог, означающий, что исполняемый файл отсутствует ContentFile когда приложение запускается.

Почему файл содержимого копируется в Library2 выходной каталог, но не Executable "S? Есть ли способ также скопировать его в последний (я хотел бы сделать это без событий сборки, потому что я уверен, что люди забудут об этом)?

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

Использование событий после сборки (например, xcopy ../Library/bin/Debug/SomeDll.dll bin/Debug); и вручную установить выходной каталог проектов в $(SolutionDir)/bin/... вместо значения по умолчанию (для каждого проекта) оба быстро превратились в огромный беспорядок. Добавление файлов содержимого в качестве ссылок в "основной проект" также было слишком утомительным. Было бы хорошо, если бы C# имел ту же настройку по умолчанию для выходного файла, что и Visual C++ (то есть $SolutionDir/$Platform/$Configuration), но это не так.

Я также решил не использовать стандартную процедуру MSBuild вообще и написать собственную цель сборки (например, использование gcc в Atmel Studio), но я совсем не продвинулся. Кроме того, я хочу, чтобы стандартные команды Visual Studio "Build" и "Debug" работали так, как обычно.


ОБНОВИТЬ:

Вот более подробно о том, что я делаю.

У меня есть решение с Executable проект. Кроме того, есть несколько проектов, которые вы можете назвать Plugin s. Executable ссылается на все эти Plugin с помощью ссылки на управляемый проект.

Поскольку проекты плагинов адаптированы к исполняемому файлу, но могут иметь компоненты многократного использования, основная функциональность часто реализуется в виде External проект, оставляя Plugin проект простой обертки (не всегда, хотя).

Сказал External проекты иногда используют собственные библиотеки DLL, предоставленные третьими сторонами. Эти библиотеки затем добавляются в External проект как файл содержимого и Copy to output dir установлен в Copy always, Таким образом, структура выглядит как на схеме выше:

External <---------------[is not aware of]--------------------+
--------                                                      |
.cs files <--[reference]-- PluginWrapper <--[reference]-- Executable
"Native DLL"               -------------                  ----------
                           .cs files                      .cs files

Странно то, что "Native DLL" копируется в External выходной каталог (очевидно), а также PluginWrapper х, но не Executable "S.

Рабочий процесс разработчика должен был бы написать External которая работает как полностью изолированная сущность (они используются очень часто), оберните ее PluginWrapper, а затем только добавить ссылку на проект в PluginWrapper в Executable, Я нахожу странным, что это, по-видимому, такая необычная вещь.

Я думал, что, возможно, редактирование ExecutableЦелевой XML MSBuild (также включающий файлы содержимого с косвенной ссылкой) мог бы решить проблему.

Я мог бы хотеть рассмотреть добавление библиотек DLL к проектам в качестве встроенных ресурсов, как это было предложено, но внедрение таких встроенных библиотек DLL мне кажется странным. В конце концов, измените рабочий процесс разработчика, убрав "[не знает]" из приведенной выше диаграммы и добавив ссылку на проект в External как предположила Бренда Белл, может быть самым разумным решением, даже если не идеальным.

Обновление 2

Обратите внимание, что идея встроенного ресурса может работать не во всех случаях. Если необходимо поместить зависимость в каталог исполняемого файла (не cwd или что-либо еще), это может не сработать из-за отсутствия прав администратора в папке установки (для распаковки файла из встроенного ресурса). Звучит странно, но это была серьезная проблема с одной из сторонних библиотек, которые мы использовали.

4 ответа

Решение

Добавьте ссылку Library1 в исполняемый проект.

РЕДАКТИРОВАТЬ:

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

-

ИМО вы ищете встроенный ресурс, а не файлы содержимого.

Когда вы компилируете библиотеку 1, файлы содержимого помещаются в ее папку bin. Когда библиотека 2 компилируется, компилятор распознает ссылочный код и включает его (Library 1.dll), но файлы содержимого не распознаются, поскольку они нигде не упоминаются в библиотеке 2. То же самое происходит при связывании библиотеки 2 с исполняемым файлом.

Если ваши файлы содержимого являются относительно небольшими (значки, шаблоны и т. Д.), И вам не нужно редактировать их, если вы потеряете исходный код, тогда вы можете встроить их в качестве ресурсов и предоставить открытый метод для возврата содержимого, такой как:

 public static Stream GetResourceContent(string rName){
     string resName = System.Reflection.Assembly
         .GetExecutingAssembly().GetManifestResourceNames()
         .FirstOrDefault(rn => rn.EndsWith("."+rName));
    if(resName!=null)
        return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resName);
    else
        return null;
}

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

Другой вариант - встроить ContentFile как ресурс в сборку Library1 и извлечь ее с помощью Assembly.GetManifestResource().

Смотрите эти ссылки для получения дополнительной информации:

http://www.attilan.com/2006/08/accessing-embedded-resources-using.html

http://blogs.msdn.com/b/alexdan/archive/2007/12/19/loading-embedded-resources-in-c-using-getmanifestresourcestream.aspx

Одним из вариантов ответа Бренды будет добавление файла (ов) библиотеки1 в качестве ссылки (ссылок) в исполняемом проекте. У вас все еще есть записи в проекте, но вам не нужно управлять несколькими копиями каждого файла.

Возможно, вы ссылаетесь на Library1 только из файла XAML, в этом случае Visual Studio не распознает использование. Также добавьте ссылку в код, например, применив атрибут name

Другие вопросы по тегам