我有以下的项目结构:
Library1 <--[project reference]-- Library2 <--[ref]-- Executable
-------- -------- ----------
ContentFile .cs files .cs files
.cs files
所有项目引用的都是CopyLocal = true。
当我构建项目时,ContentFile会被复制到Library2的输出目录,但不会被复制到Executable的输出目录,这意味着当应用程序运行时,可执行文件缺少ContentFile。
为什么ContentFile会被复制到Library2的输出目录,而不是Executable的输出目录?有没有办法也将其复制到后者(我想这样做而又不使用构建事件,因为我确定人们会忘记)?
我正在寻求一个合理且可维护的解决方案;一种在添加新项目或间接引用的内容文件时需要最小化工作量的解决方案,以便尽可能避免简单地忘记它。
使用Post-Build事件(例如xcopy ../Library/bin/Debug/SomeDll.dll bin/Debug);手动设置项目的输出目录为$(SolutionDir)/bin/...而不是默认值(按项目分配),两者都很快变得混乱。将内容文件作为链接添加到“主项目”中也太繁琐了。如果C#具有与Visual C++相同的默认设置,使输出文件位于$SolutionDir/$Platform/$Configuration,那就好了,但实际上并非如此。
我还考虑过根本不使用标准MSBuild过程,而是编写自定义构建目标(就像在Atmel Studio中使用gcc一样),但我根本就没有进展。此外,我希望Visual Studio的标准“Build”和“Debug”命令像往常一样工作。
更新:
这是我正在做的更多细节。
我有一个解决方案,其中包含一个Executable项目。此外,还有一堆你可以称之为插件的项目。Executable通过托管项目引用引用所有这些插件。
由于插件项目是针对可执行文件定制的,但可能具有可重用组件,因此主要功能通常在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
奇怪的是,“本机DLL”会被复制到External
的输出目录中(显然),以及PluginWrapper
的输出目录,但不会复制到Executable
的输出目录。
开发者的工作流程是编写一个完全隔离的实体External
(它们经常被重用),用PluginWrapper
包装它,然后只将PluginWrapper
的项目引用添加到Executable
。我觉得这样做似乎很少见。
我想也许可以通过编辑Executable
的MSBuild目标XML(包括间接引用的内容文件)来解决问题。
虽然我可能会考虑像建议的那样将DLL添加到项目中作为嵌入式资源,但是嵌入本机DLL看起来很奇怪。最终,像Brenda Bell建议的那样去掉上图中"[is not aware of]"并添加对External
的项目引用,可能是最明智的解决方案,即使不是理想的。
更新2
请注意,嵌入资源的想法可能并非在所有情况下都适用。如果需要将依赖项放置在可执行文件的目录中(而不是cwd或其他任何地方),则可能由于安装文件夹中缺少管理员权限(以从嵌入式资源中解压文件),而无法实现。听起来很奇怪,但这是我们使用的第三方库之一的严重问题。
$(SolutionDir)/bin/...
而不是默认的(按项目基础),这两者都很快变得一团糟。在“主项目”中添加内容文件作为链接也太繁琐了。 - dialer