在我的Visual Studio解决方案中,我有四个项目(每个项目都针对。net 3.5)——对于我的问题,只有这两个是重要的:

这个类库引用了一个第三方DLL文件(elma . DLL) 这个web应用程序项目有一个对MyBaseProject的引用

我通过点击“添加引用…”将elmah.dll引用添加到Visual studio 2008中的MyBaseProject中。→“浏览”选项卡→选择“elmah.dll”。

Elmah Reference的属性如下:

别名-全局 本地复制- true 文化- - - - - - 错误日志模块和处理程序(ELMAH)。网 文件类型-程序集 路径- D:\webs\otherfolder\_myPath\__tools\elmah\ elmah .dll 解决-正确 运行时版本- v2.0.50727 指定版本- false 强名称- false 版本- 1.0.11211.0

在MyWebProject1中,我通过以下方式添加了对项目MyBaseProject的引用: “添加引用……”→“项目”标签→选择“MyBaseProject”。除了以下成员之外,该引用的属性是相同的:

描述- - - 路径- D:\web \CMS\MyBaseProject\bin\Debug\MyBaseProject.dll 版本- 1.0.0.0

如果我在Visual Studio中运行构建,elmah.dll文件将被复制到我的MyWebProject1的bin目录中,以及MyBaseProject.dll!

但是,如果我清理并运行解决方案的MSBuild(通过D:\web \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中"copy local"的别名):

<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说“copy local”为真。我切换“复制本地”为假-保存-并将其设置为真-保存!)

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 . somefunction())。现在,您创建了一个引用项目X的新项目Y。

所以依赖链是这样的:Y => X => A => B

Visual Studio / MSBuild试图变得聪明,只把它检测到项目X需要的引用引入项目Y;它这样做是为了避免项目Y中的引用污染。问题是,由于项目X实际上不包含任何显式使用程序集B的代码(例如B.SomeFunction()), VS/MSBuild不会检测到X需要B,因此不会将B复制到项目Y的bin目录中;它只复制X和A程序集。

解决方案

您有两个选项来解决这个问题,这两个选项都将导致程序集B被复制到项目Y的bin目录:

在项目Y中添加对程序集B的引用。 向项目X中使用程序集B的文件添加伪代码。

就我个人而言,出于几个原因,我更喜欢第二种选择。

If you add another project in the future that references project X, you won't have to remember to also include a reference to assembly B (like you would have to do with option 1). You can have explicit comments saying why the dummy code needs to be there and not to remove it. So if somebody does delete the code by accident (say with a refactor tool that looks for unused code), you can easily see from source control that the code is required and to restore it. If you use option 1 and somebody uses a refactor tool to clean up unused references, you don't have any comments; you will just see that a reference was removed from the .csproj file.

下面是我遇到这种情况时通常添加的“伪代码”示例。

    // 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);
    }

其他回答

我刚刚遇到了一个非常相似的问题。使用Visual Studio 2010编译时,DLL文件包含在bin文件夹中。但是当使用MSBuild编译时,第三方DLL文件不包括在内。

非常令人沮丧。我解决这个问题的方法是在我的web项目中包含NuGet引用,即使我没有直接使用它。

使用致命狗的方案,

Y => x => a => b,

我的问题是当我构建Y时,X中的程序集(A和B,所有15个)没有显示在Y的bin文件夹中。

我从Y中删除引用X,保存,构建,然后重新添加X引用(一个项目引用),保存,构建,然后a和B开始出现在Y的bin文件夹中。

我今天也遇到了类似的问题,这肯定不是你问题的答案。但我想告诉大家,并可能提供一些见解。

我有一个ASP。网络应用程序。构建过程被设置为清理然后构建。

我有两个詹金斯的CI脚本。一个用于制作,一个用于分期。我将应用程序部署到登台,一切工作正常。已部署到生产环境,并且缺少一个引用的DLL文件。这个DLL文件只是在项目的根目录中。不在任何NuGet存储库中。DLL被设置为不复制。

两个部署之间的CI脚本和应用程序是相同的。在暂存环境中的清理和部署之后,DLL文件在ASP. DLL的部署位置被替换。NET应用程序(bin/)。但在生产环境中却不是这样。

结果在一个测试分支中,我在构建过程中添加了一个步骤,将这个DLL文件复制到bin目录。现在我花了一点时间才算出来。CI过程本身没有清洁。DLL被留在工作目录中,并被意外地与ASP打包在一起。. NET .zip文件。生产分支从来没有以同样的方式复制DLL文件,也从来没有意外地部署过它。

TLDR;检查并确保您知道构建服务器正在做什么。

来看看:

这个MSBuild论坛线程是我开始的

你会在那里找到我的临时解决办法!

(MyBaseProject需要一些代码来引用elma .dll中的一些类(无论什么),因为elma .dll被复制到MyWebProject1的bin中!)

我也有同样的问题。

检查项目的框架版本是否与您引用的dll的框架版本相同。

在我的例子中,我的客户端是使用“Framework 4客户端”编译的,DLL在“Framework 4”中。