我的 Visual Studio 解决方案中有四个项目(每个人都针对 .NET 3.5) - 对于我的问题,只有这两个很重要:
我在 Visual Studio 2008 中添加了对 MyBaseProject 的 elmah.dll 引用, 方法 是单击“添加引用…”-“浏览”选项卡-选择“elmah.dll”。
Elmah 参考的属性如下:
在 MyWebProject1 中 ,我通过以下方式添加了对 Project MyBaseProject 的引用:“添加引用…”——“项目”选项卡——选择“MyBaseProject”。除了以下成员之外,此引用的属性相同:
如果我在 Visual Studio 中运行构建,elmah.dll 文件将与 MyBaseProject.dll 一起复制到 MyWebProject1 的 bin 目录中!
但是,如果我为解决方案清理并运行 MSBuild (通过 D:\webs\CMS> C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln ) MyWebProject1 的 bin 目录 中缺少 elmah.dll - 尽管构建本身不包含警告或错误!
我已经确保 MyBaseProject 的 .csproj 包含值为“true”的 私有 元素(这应该是Visual Studio中“ 复制本地”的别名):
<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\mypath\__tools\elmah\Elmah.dll</HintPath> **<Private>true</Private>** </Reference>
(默认情况下,私有标签没有出现在 .csproj 的 xml 中,尽管 Visual Studio 说“复制本地”为真。我将“复制本地”切换为假 - 已保存 - 并再次将其设置回真 - 保存!)
MSBuild 有什么问题? 如何将 (elmah.dll) 引用复制到 MyWebProject1 的 bin 中?
我不想在每个项目的 postbuild 命令中添加 postbuild 复制操作!(想象一下我会有很多项目依赖于 MyBaseProject!)
我不确定为什么在 Visual Studio 和 MsBuild 之间构建时会有所不同,但这是我在 MsBuild 和 Visual Studio 中遇到此问题时发现的。
对于示例场景,假设我们有项目 X、程序集 A 和程序集 B。程序集 A 引用程序集 B,因此项目 X 包含对 A 和 B 的引用。此外,项目 X 包含引用程序集 A 的代码(例如 A.一些函数())。现在,您创建一个引用项目 X 的新项目 Y。
所以依赖链看起来像这样: Y = > X => A => B
Visual Studio / MSBuild 试图变得聪明,只将引用引入项目 Y,它检测到项目 X 需要它;它这样做是为了避免项目 Y 中的引用污染。问题是,由于项目 X 实际上不包含任何明确使用程序集 B 的代码(例如 B.SomeFunction()),VS/MSBuild 没有检测到 B 是必需的通过 X,因此不会将其复制到项目 Y 的 bin 目录中;它只复制 X 和 A 程序集。
你有两个选项来解决这个问题,这两个选项都会导致程序集 B 被复制到项目 Y 的 bin 目录中:
出于几个原因,我个人更喜欢选项 2。
这是我遇到这种情况时通常添加的“虚拟代码”示例。
// DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!! private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE() { // Assembly A is used by this file, and that assembly depends on assembly B, // but this project does not have any code that explicitly references assembly B. Therefore, when another project references // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well. var dummyType = typeof(B.SomeClass); Console.WriteLine(dummyType.FullName); }