我的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中“复制本地”的别名工作室):
<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”为true。我将“copy local”切换为false - 保存 - 并再次将其设置为true - 保存! )
MSBuild有什么问题?如何将(elmah.dll)引用复制到MyWebProject1的bin?
我不想在每个项目的postbuild命令中添加postbuild复制操作! (想象一下,我会有很多项目依赖于MyBaseProject!)
答案 0 :(得分:166)
我只是像这样处理它。转到参考的属性并执行以下操作:
Set "Copy local = false"
Save
Set "Copy local = true"
Save
就是这样。
Visual Studio 2010最初并未放入:
引用标记中的<private>True</private>
并将“copy local”设置为false会导致它创建标记。之后它将相应地设置为true和false。
答案 1 :(得分:143)
我不确定为什么在Visual Studio和MsBuild之间构建时会有所不同,但这是我在MsBuild和Visual Studio中遇到此问题时发现的内容。
对于示例场景,假设我们有项目X,程序集A和程序集B.程序集A引用程序集B,因此项目X包含对A和B的引用。此外,项目X包含引用程序集A的代码(例如A.SomeFunction())。现在,您创建一个引用项目X的新项目Y。
因此依赖关系链如下所示: Y =&gt; X =&gt; A =&gt;乙强>
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);
}
答案 2 :(得分:38)
如果您没有直接在代码中使用程序集,那么Visual Studio在尝试提供帮助时会检测到它未被使用,并且不会将其包含在输出中。我不确定为什么你会在Visual Studio和MSBuild之间看到不同的行为。您可以尝试将构建输出设置为两者的诊断,并比较结果,看看它的分歧。
对于你的elmah.dll引用,如果你没有直接在代码中引用它,可以将它作为项添加到项目中,并将Build Action设置为Content
,将Copy to Output Directory设置为{{1 }}
答案 3 :(得分:14)
看看:
This MSBuild forum thread I started
你会在那里找到我的临时解决方案/解决方法!
(MyBaseProject需要一些引用elmah.dll中某些类(无论如何)的代码,以便将elmah.dll复制到MyWebProject1的bin中!)
答案 4 :(得分:8)
我遇到了同样的问题。
检查项目的框架版本是否与您引用的dll的框架版本相同。
就我而言,我的客户端是使用“Framework 4 Client”编译的,DLL是在“Framework 4”中。
答案 5 :(得分:6)
我遇到的问题是我有一个依赖于图书馆项目的项目。为了构建,我遵循了以下步骤:
msbuild.exe myproject.vbproj /T:Rebuild
msbuild.exe myproject.vbproj /T:Package
这当然意味着我在bin中丢失了我的库的dll文件,最重要的是在包zip文件中。我发现这很有效:
msbuild.exe myproject.vbproj /T:Rebuild;Package
我不知道为什么这项工作或为什么它首先没有。但希望有所帮助。
答案 6 :(得分:4)
正如Alex Burtsev在评论中提到的只在XAML资源字典中使用的任何内容,或者在我的情况下,任何仅在XAML中使用而不在代码中使用的内容,都不被MSBuild视为“正在使用”。
因此,简单地在一些代码后面对程序集中的类/组件进行虚拟引用就足以让MSBuild确信该程序集实际上正在使用中。
答案 7 :(得分:4)
我遇到了完全相同的问题,结果是由于同一解决方案中的2个项目引用了第三方库的不同版本。
一旦我纠正了所有参考文献,一切都工作得很好。
答案 8 :(得分:3)
使用致命狗的计划
Y =&gt; X =&gt; A =&gt; B ,
我的问题是当我构建Y时,来自X的程序集(A和B,所有15个)都没有出现在Y的bin文件夹中。
我通过从Y中删除引用X来解决它,保存,构建,然后重新添加X引用(项目引用),并保存,构建,并且A和B开始显示在Y的bin中文件夹中。
答案 9 :(得分:3)
将目标框架从 .NET Framework 4 Client Profile 更改为 .NET Framework 4 为我解决了这个问题。
因此在您的示例中:将MyWebProject1上的目标框架设置为 .NET Framework 4
答案 10 :(得分:2)
这需要在项目中添加.targets
文件并将其设置为包含在项目的包含部分中。
有关程序,请参阅my answer here。
答案 11 :(得分:2)
另一种情况是,如果您使用旧的&#34;网站&#34; Visual Studio中的项目类型。对于该项目类型,它无法引用其自身目录结构之外的.dll(当前文件夹和向下)。所以在上面的答案中,让我们说你的目录结构如下所示:
其中ProjectX和ProjectY是父/子目录,而ProjectX引用A.dll,后者又引用B.dll,而B.dll在目录结构之外,例如在根(包)上的Nuget包中,然后将包括A.dll,但B.dll不会。
答案 12 :(得分:2)
引用在构建期间未使用的程序集不是正确的做法。您应该扩充构建文件,以便复制其他文件。通过使用post build事件或更新属性组。
其他帖子中可以找到一些例子
答案 13 :(得分:2)
我有同样的问题,dll是一个动态加载的引用。 为了解决这个问题,我在dll的命名空间中添加了“using”。 现在,dll将复制到输出文件夹中。
答案 14 :(得分:0)
我今天遇到了类似的问题,这肯定不是你问题的答案。但我想告诉大家,并可能提供一些见解。
我有一个ASP.NET应用程序。构建过程设置为clean,然后构建。
我有两个Jenkins CI个脚本。一个用于生产,一个用于分期。我将我的应用程序部署到暂存,一切正常。部署到生产并丢失了引用的DLL文件。这个DLL文件就在项目的根目录中。不在任何NuGet存储库中。 DLL设置为do not copy
。
两个部署之间的CI脚本和应用程序是相同的。仍然在暂存环境中清理和部署之后,DLL文件在ASP.NET应用程序的部署位置(bin/
)中被替换。生产环境并非如此。
事实证明,在测试分支中,我已经在构建过程中添加了一个步骤,将此DLL文件复制到bin
目录。现在需要花一点时间来弄清楚的部分。 CI过程本身并没有清理。 DLL留在工作目录中,并且意外地与ASP.NET .zip文件打包在一起。生产分支从未以相同的方式复制DLL文件,并且从不会意外地部署它。
TLDR;检查并确保您知道构建服务器正在做什么。
答案 15 :(得分:0)
我遇到了一个非常类似的问题。使用Visual Studio 2010进行编译时,DLL文件包含在bin
文件夹中。但是在使用MSBuild进行编译时,未包含第三方DLL文件。
非常令人沮丧。我解决它的方法是在我的web项目中包含NuGet对包的引用,即使我没有直接在那里使用它。
答案 16 :(得分:0)
请确保两个项目都使用相同的.net版本,并检查“复制本地”属性,但默认应为true
答案 17 :(得分:0)
使用Visual Studio 2015添加其他参数
/ deployonbuild = false
在msbuild命令行中解决了该问题。
答案 18 :(得分:-3)
在网站项目中包含项目引用中所有引用的DLL文件并不总是一个好主意,尤其是当您使用dependency injection时:您的Web项目只是想添加对接口DLL文件/项目的引用,没有任何具体的实现DLL文件。
因为如果直接向实现DLL文件/项目添加引用,则无法阻止开发人员在实现DLL文件/项目的具体类上而不是通过接口调用“new”。您也在网站上声明了使用该实施的“硬编码”。