如果在解决方案中使用项目依赖项,则MSBuild不会复制引用(DLL文件)。

300
我在Visual Studio解决方案中有四个项目(都是针对.NET 3.5),但只有这两个对我的问题很重要:
1. MyBaseProject <- 这个类库引用了第三方DLL文件(elmah.dll) 2. MyWebProject1 <- 这个Web应用程序项目引用了MyBaseProject
我通过点击 "添加引用..." -> "浏览"选项卡 -> 选择"elmah.dll" 在 Visual Studio 2008 中将 elmah.dll 引用添加到 MyBaseProject。Elmah 引用的属性如下:
- 别名 - 全局 - 复制本地 - true - 文化 - - 描述 - 用于 ASP.NET 的错误日志记录模块和处理程序 (ELMAH) - 文件类型 - 程序集 - 路径 - D:\webs\otherfolder\_myPath__tools\elmah\Elmah.dll - 已解析 - True - 运行时版本 - v2.0.50727 - 指定版本 - false - 强名称 - false - 版本 - 1.0.11211.0
在 MyWebProject1 中,我通过 "添加引用..." -> "项目"选项卡 -> 选择"MyBaseProject" 来添加对 MyBaseProject 项目的引用。该引用的属性与上述相同,除了以下成员:
- 描述 - - 路径 - D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll - 版本 - 1.0.0.0
如果我在 Visual Studio 中运行构建,则 elmah.dll 文件将与MyBaseProject.dll一起复制到 MyWebProject1 的bin目录中!但是,如果我清理并通过 D:\webs\CMS> C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln 来运行解决方案的 MSBuild,则在MyWebProject1的bin目录中缺少 elmah.dll——尽管构建本身没有警告或错误!
我已经确保 MyBaseProject 的 .csproj 包含具有值 "true" 的 private 元素 (这应该是 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显示“复制本地”为true。我将“复制本地”设置为false,保存,然后再设置为true - 保存! MSBuild出了什么问题?如何才能让(elmah.dll)引用被复制到MyWebProject1的bin目录下?我不想在每个项目的后期构建命令中添加复制操作!(想象一下,如果有很多项目依赖于MyBaseProject!)

12
我希望您能给出更清晰的答案,解释为什么会发生这种情况。 - David Faivre
1
请查看此处提供的答案:https://dev59.com/UXNA5IYBdhLWcg3wPLL-#12076542 - Anuroopa Shenoy
1
有没有完整的源代码示例,可以作为最终解决方案? - Kiquenet
2
请查看@deadlydog在https://dev59.com/PXNA5IYBdhLWcg3wAIxP#21055664下的答案。他给出了非常好的解释并且解决了我的问题……下面得票最高的答案对于VS2012是不正确的。 - Jeff Widmer
2
请投赞成票:https://connect.microsoft.com/VisualStudio/feedback/details/652785/visual-studio-does-not-copy-referenced-assemblies-through-the-reference-hierarchy - Zack
就我所知,我认为这个属性在某个时候被NuGet删除了。 - Worthy7
20个回答

3
另一个出现这种情况的场景是,如果您在Visual Studio中使用旧版“网站”项目类型。 对于该项目类型,它无法引用位于其目录结构之外(当前文件夹和子文件夹)的.dll文件。 因此,在上面的答案中,假设您的目录结构如下:

enter image description here

当ProjectX和ProjectY是父/子目录时,ProjectX引用A.dll,而A.dll又引用B.dll,而B.dll位于目录结构之外,例如在根目录(Packages)的Nuget包中,则A.dll将被包含,但B.dll不会。


3
这需要将一个.targets文件添加到您的项目中,并将其设置为包括在项目的包含部分中。
请参见这里的我的答案了解详细步骤。

3

3

我之前也遇到了相同的问题,而且dll是动态加载的引用。 为了解决这个问题,我添加了一个"using"并加上了dll的命名空间。 现在dll已经被复制到输出文件夹中。


2

使用Visual Studio 2015,在msbuild命令行中添加附加参数

/deployonbuild=false

可以解决此问题。


/p:DeployOnBuild=False 对于使用 Visual Studio 2022 部署的 msbuild.exe 的命令行使用仍然有帮助。 - undefined

2

我今天遇到了类似的问题,但这绝不是你问题的答案。但我想通知每个人,并可能提供一点见解。

我有一个ASP.NET应用程序,构建过程设置为清理然后构建。

我有两个JenkinsCI脚本,一个用于生产,一个用于暂存。我将应用程序部署到了暂存环境,一切正常。将其部署到生产环境时,缺少引用的DLL文件。此DLL文件就在项目的根目录中,而不在任何NuGet存储库中。 DLL设置为不复制

CI脚本和应用程序在两个部署之间是相同的。即使在暂存环境中进行了清理和部署,DLL文件仍会被替换在ASP.NET应用程序的部署位置( bin / )。但在生产环境中并非如此。

原来在测试分支上,我已经添加了一个步骤到构建过程中,将该 DLL 文件复制到“bin”目录。现在需要花一点时间解决的问题是 CI 过程没有自我清理。DLL 文件留在了工作目录中,并且意外地与 ASP.NET .zip 文件一起打包。生产分支从未以同样的方式复制过 DLL 文件,也从未意外部署它。
简而言之,检查并确保你知道你的构建服务器正在做什么。

1
确保两个项目使用相同的 .net 版本,同时检查“复制本地”属性,但这应该默认为 true

0

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

msbuild -t:clean,rebuild,pack

0

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

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


1
这是一个顶部答案的复制。 - Giles Roberts

-2
在网站项目中包含所有从项目引用的 DLL 文件并不总是一个好主意,特别是当你正在使用依赖注入时:你的 Web 项目只想添加对接口 DLL 文件/项目的引用,而不是任何具体实现的 DLL 文件。
因为如果你直接添加对实现 DLL 文件/项目的引用,你就无法防止开发人员调用实现 DLL 文件/项目的具体类而不是通过接口。这也会在你的网站中声明一个“硬编码”来使用该实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接