在我的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!)


来看看:

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

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

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

如果你没有在代码中直接使用程序集,那么Visual Studio会检测到它没有被使用,并且不会在输出中包含它。我不知道为什么你看到Visual Studio和MSBuild之间有不同的行为。您可以尝试将构建输出设置为诊断输出,并比较结果,看看它在哪里出现分歧。

至于你的elma .dll引用,如果你没有在代码中直接引用它,你可以将它作为一个项目添加到你的项目中,并将构建操作设置为内容,将复制到输出目录设置为始终。

我就是这样处理的。转到你引用的属性,这样做:

Set "Copy local = false"
Save
Set "Copy local = true"
Save

就是这样。

Visual Studio 2010最初并没有: <private>True</private>在引用标签中,并将“copy local”设置为false会导致它创建标签。然后,它将相应地将其设置为true和false。

我也有同样的问题。

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

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

我有同样的问题,dll是一个动态加载的引用。 为了解决这个问题,我在dll的命名空间中添加了一个“using”。 现在dll被复制到输出文件夹中。

我面临的问题是我有一个依赖于图书馆项目的项目。为了制作游戏,我遵循了以下步骤:

msbuild.exe myproject.vbproj /T:Rebuild
msbuild.exe myproject.vbproj /T:Package

这当然意味着我在bin中丢失了我的库的dll文件,最重要的是在包zip文件中。我发现这非常有效:

msbuild.exe myproject.vbproj /T:Rebuild;Package

我不知道为什么它会起作用,也不知道为什么它一开始就不起作用。但希望这能有所帮助。

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

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

将目标框架从. net framework 4客户端配置文件更改为. net framework 4为我解决了这个问题。

所以在你的例子中:将MyWebProject1上的目标框架设置为.NET framework 4

正如Alex Burtsev在评论中提到的,任何只在XAML资源字典中使用的东西,或者在我的例子中,任何只在XAML中使用而不在后面的代码中使用的东西,都不会被MSBuild视为“在使用中”。

因此,只需在后面的一些代码中对程序集中的类/组件新建一个虚拟引用,就足以使MSBuild相信该程序集中确实在使用。

这需要将.targets文件添加到项目中,并将其设置为包含在项目的includes部分中。

请看我在这里回答的程序。

引用构建期间未使用的程序集不是正确的实践。您应该扩展构建文件,以便它复制其他文件。可以使用生成后事件,也可以更新属性组。

一些例子可以在其他帖子中找到

作为项目依赖项的一部分,复制动态生成的文件 如何在项目中包含文件,在构建或发布期间自动将它们复制到构建输出目录

在Website项目中包含项目引用中所有引用的DLL文件并不总是一个好主意,特别是当你使用依赖项注入时:你的web项目只是想添加一个对接口DLL文件/项目的引用,而不是任何具体的实现DLL文件。

因为如果您直接向实现DLL文件/项目添加引用,您不能阻止开发人员在实现DLL文件/项目的具体类上调用“new”,而不是通过接口。你也已经在你的网站上声明了一个“硬代码”来使用这个实现。

我不确定为什么在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);
    }

我只是遇到了完全相同的问题,结果是由于同一解决方案中的两个项目引用了不同版本的第三方库。

一旦我纠正了所有的参考资料,一切都很完美。

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

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

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

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

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

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

使用致命狗的方案,

Y => x => a => b,

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

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

出现这种情况的另一种情况是,如果您在Visual Studio中使用旧的“Web Site”项目类型。对于该项目类型,它无法引用它自己目录结构(当前文件夹和下)之外的.dll。在上面的答案中,假设你的目录结构是这样的:

如果ProjectX和ProjectY是父/子目录,并且ProjectX引用a .dll,后者又引用B.dll,而B.dll在目录结构之外,例如在根目录(Packages)的Nuget包中,那么a .dll将被包括在内,而B.dll将不包括在内。

确保两个项目都在相同的.net版本中,并检查copy local属性,但这应该是默认值

使用Visual Studio 2015添加附加参数

/ deployonbuild = false

到msbuild命令行修复了该问题。

我认为@deadlydog的答案在当前的Nuget系统中是无效的。我在visual studio 2022中重新创建了Y => X => A => B的场景,我所要做的就是在终端中运行命令

msbuild -t:clean,rebuild,pack