У меня есть следующая структура проекта:
Library1 <--[project reference]-- Library2 <--[ref]-- Executable
-------- -------- ----------
ContentFile .cs files .cs files
.cs files
Все ссылки на проект имеют CopyLocal = true.
Когда я создаю проект, ContentFile копируется в каталог вывода Library2, но не в каталог Executable output, что означает, что при запуске приложения отсутствует ContentFile.
Почему файл содержимого копируется в каталог Library2 output, но не Executable? Есть ли способ скопировать его в последнюю (я бы хотел сделать это без событий сборки, потому что я уверен, что люди это забудут)?
Я ищу разумное и поддерживаемое решение; тот, который требует минимальных усилий при добавлении новых проектов или новых косвенно связанных файлов содержимого, так что как можно мало просто забыть об этом.
Использование событий Post-Build (например, xcopy ../Library/bin/Debug/SomeDll.dll bin/Debug); и вручную устанавливая выходной каталог проектов на $(SolutionDir)/bin/... вместо стандартного (для каждого проекта), оба быстро становятся огромным беспорядком. Добавление файлов содержимого в виде ссылок в "основной проект" было слишком утомительным. Было бы замечательно, если бы С# имел тот же самый параметр по умолчанию для выходного файла, что и Visual С++ (т.е. $SolutionDir/$Platform/$Configuration), но это не так.
Я также рассматривал возможность использования стандартной процедуры MSBuild вообще и запись пользовательской цели сборки (например, использование gcc в Atmel Studio), но я совсем не ушел. Кроме того, я хочу, чтобы стандартные команды "Build" и "Debug" Visual Studio работали так, как обычно.
UPDATE:
Вот более подробно о том, что я делаю.
У меня есть решение с проектом Executable. Кроме того, существует множество проектов, которые вы могли бы назвать Plugin s. Executable ссылается на все те Plugin через управляемую ссылку на проект.
Поскольку проекты плагина адаптируются к исполняемому файлу, но могут иметь многоразовые компоненты, основная функциональность часто реализуется в проекте External, оставляя проект Plugin простой оболочкой (не всегда).
Указанные проекты External иногда используют собственные DLL файлы, предоставляемые третьими лицами. Затем эти 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.
Тогда рабочий процесс разработчика должен был бы написать External, который будет работать как полностью изолированный объект (они часто используются повторно), оберните его с помощью PluginWrapper, а затем добавьте ссылку на проект в PluginWrapper до Executable. Мне показалось странным, что это, по-видимому, такая необычная вещь.
Я подумал, что, возможно, редактирование Executable целевого XML файла MSBuild (включая косвенно связанные файлы содержимого) могло решить проблему.
Возможно, мне захочется заглянуть в добавление DLL к проектам в виде встроенных ресурсов, как было предложено, но встраивание таких DLL, как это кажется мне странным. В конце концов, сменив рабочий процесс разработчика, разделив "[не знаю]" на приведенной выше диаграмме и добавив ссылку на проект на External, как предложила Бренда Белл, может быть самым разумным решением, даже если оно не идеально.
Обновление 2
Обратите внимание, что встроенная идея resouce может не работать во всех случаях. Если необходимо установить зависимость в исполняемом каталоге (не cwd или что-то еще), это может не работать из-за отсутствия привилегий администратора в папке установки (чтобы распаковать файл из встроенного ресурса). Звучит странно, но это была серьезная проблема с одной из сторонних библиотек, которые мы использовали.