我有以下项目结构:
Library1 <--[project reference]-- Library2 <--[ref]-- Executable
-------- -------- ----------
ContentFile .cs files .cs files
.cs files
所有项目引用都具有 CopyLocal = true。
当我构建项目时,ContentFile
被复制到Library2
的输出目录,而不是Executable
的输出目录,这意味着ContentFile
应用程序运行时缺少可执行文件。
为什么内容文件被复制到Library2
's 的输出目录,而不是Executable
's?有没有办法将它也复制到后者(我想在没有构建事件的情况下这样做,因为我相信人们会忘记这一点)?
我正在寻找一个合理且可维护的解决方案;在添加新项目或新的间接引用的内容文件时需要最少的努力,因此不太可能简单地忘记这样做。
使用构建后事件(如xcopy ../Library/bin/Debug/SomeDll.dll bin/Debug
);并手动将项目的输出目录设置为$(SolutionDir)/bin/...
而不是默认(基于每个项目),都很快变得一团糟。在“主项目”中添加内容文件作为链接也太乏味了。如果 C# 的输出文件具有与 Visual C++ 相同的默认设置(即$SolutionDir/$Platform/$Configuration
),那会很好,但事实并非如此。
我还考虑过根本不使用标准的 MSBuild 程序并编写自定义构建目标(例如在 Atmel Studio 中使用 gcc),但我并没有走多远。此外,我希望 Visual Studio 的标准“构建”和“调试”命令能够像往常一样工作。
更新:
这里有更多关于我在做什么的细节。
我有一个Executable
项目的解决方案。此外,还有很多项目可以称为Plugin
s。通过托管项目引用Executable
引用所有这些。Plugin
由于插件项目是为可执行文件量身定制的,但可能具有可重用的组件,因此主要功能通常在External
项目中实现,而Plugin
项目只是一个包装器(尽管并非总是如此)。
所述External
项目有时使用第三方提供的本地 DLL。然后将这些 DLLExternal
作为内容文件添加到项目中并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
's 的输出目录(显然),还有 PluginWrapper
's,但不是 Executable
's。
然后,开发人员的工作流程将是编写一个External
作为完全隔离的实体工作的一个(它们经常被重用),用 a 包装它PluginWrapper
,然后只添加一个对 to 的项目PluginWrapper
引用Executable
。我觉得很奇怪,这显然是一件不寻常的事情。
我认为也许编辑Executable
的 MSBuild 目标 XML(也包括间接引用的内容文件)可以解决问题。
我可能想考虑按照建议将 DLL 作为嵌入式资源添加到项目中,但是像这样嵌入本机 DLL 对我来说似乎很奇怪。最后,正如 Brenda Bell 建议的那样,通过从上图中删除“[不知道]”并添加对 的项目引用来更改开发人员的工作流程External
可能是最明智的解决方案,即使不是理想的解决方案。
更新 2
请注意,嵌入式资源的想法可能不适用于所有情况。如果需要在可执行文件的目录中放置依赖项(不是 cwd 或任何东西),那么这可能无法正常工作,因为安装文件夹中缺少管理员权限(从嵌入式资源中解压缩文件)。听起来很奇怪,但这是我们使用的第 3 方库之一的严重问题。