visual-studio 如果在解决方案中使用项目依赖项,MSBuild 不会复制引用(DLL 文件)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1132243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MSBuild doesn't copy references (DLL files) if using project dependencies in solution
提问by toebens
I have four projects in my Visual Studio solution (everyone targeting .NET 3.5) - for my problem only these two are important:
我的 Visual Studio 解决方案中有四个项目(每个人都针对 .NET 3.5) - 对于我的问题,只有这两个很重要:
- MyBaseProject<- this class library references a third-party DLL file (elmah.dll)
- MyWebProject1<- this web application project has a reference to MyBaseProject
- MyBaseProject<- 此类库引用了第三方 DLL 文件 (elmah.dll)
- MyWebProject1<- 此 Web 应用程序项目引用了 MyBaseProject
I added the elmah.dll reference to MyBaseProjectin Visual studio 2008 by clicking "Add reference..." → "Browse" tab → selecting the "elmah.dll".
我加入了elmah.dll参考MyBaseProject通过点击在Visual Studio 2008中的“添加引用...”→“浏览”选项卡→选择“elmah.dll”。
The Properties of the Elmah Reference are as follows:
Elmah 参考的属性如下:
- Aliases - global
- Copy local - true
- Culture -
- Description - Error Logging Modules and Handlers (ELMAH) for ASP.NET
- File Type - Assembly
- Path - D:\webs\otherfolder\_myPath\__tools\elmah\Elmah.dll
- Resolved - True
- Runtime version - v2.0.50727
- Specified version - false
- Strong Name - false
- Version - 1.0.11211.0
- 别名 - 全局
- 复制本地 - 真
- 文化 -
- 描述 - 用于 ASP.NET 的错误记录模块和处理程序 (ELMAH)
- 文件类型 - 装配
- 路径 - D:\webs\otherfolder\_myPath\__tools\elmah\Elmah.dll
- 已解决 - 真
- 运行时版本 - v2.0.50727
- 指定版本 - false
- 强名称 - 假
- 版本 - 1.0.11211.0
In MyWebProject1I added the reference to Project MyBaseProject by: "Add reference..." → "Projects" tab → selecting the "MyBaseProject". The Properties of this reference are the same except the following members:
在MyWebProject1 中,我通过以下方式添加了对 Project MyBaseProject 的引用:“添加引用...”→“项目”选项卡→选择“MyBaseProject”。除了以下成员外,此引用的属性相同:
- Description -
- Path - D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll
- Version - 1.0.0.0
- 描述 -
- 路径 - D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll
- 版本 - 1.0.0.0
If I run the build in Visual Studiothe elmah.dll file is copied to my MyWebProject1's bindirectory, along with MyBaseProject.dll!
如果我在Visual Studio 中运行构建,elmah.dll 文件将与 MyBaseProject.dll 一起复制到我的MyWebProject1 的 bin目录中!
However if I clean and run MSBuildfor the solution (via D:\webs\CMS> C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln) the elmah.dll is missingin MyWebProject1's bin directory - although the build itself contains no warning or errors!
但是,如果我为解决方案清理并运行MSBuild(通过 D:\webs\CMS> C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln ) MyWebProject1 的 bin 目录中缺少elmah.dll - 尽管构建本身不包含警告或错误!
I already made sure that the .csproj of MyBaseProject contains the privateelement with the value "true" (that should be an alias for "copy local" in Visual Studio):
我已经确保 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>
(The private tag didn't appear in the .csproj's xml by default, although Visual Studio said "copy local" true. I switched "copy local" to false - saved - and set it back to true again - save!)
(默认情况下,私有标记没有出现在 .csproj 的 xml 中,尽管 Visual Studio 说“复制本地”为真。我将“复制本地”切换为假 - 保存 - 并再次将其设置回真 - 保存!)
What is wrong with MSBuild? How do I get the (elmah.dll) reference copied to MyWebProject1's bin?
MSBuild 有什么问题?如何将 (elmah.dll) 引用复制到 MyWebProject1 的 bin?
I do NOT want to add a postbuild copy action to every project's postbuild command! (Imagine I would have many projects depend on MyBaseProject!)
我不想在每个项目的 postbuild 命令中添加 postbuild 复制操作!(想象一下我会有很多项目依赖于 MyBaseProject!)
采纳答案by deadlydog
I'm not sure why it is different when building between Visual Studio and MsBuild, but here is what I have found when I've encountered this problem in MsBuild and Visual Studio.
我不确定为什么在 Visual Studio 和 MsBuild 之间构建时会有所不同,但这是我在 MsBuild 和 Visual Studio 中遇到此问题时所发现的。
Explanation
解释
For a sample scenario let's say we have project X, assembly A, and assembly B. Assembly A references assembly B, so project X includes a reference to both A and B. Also, project X includes code that references assembly A (e.g. A.SomeFunction()). Now, you create a new project Y which references project X.
对于示例场景,假设我们有项目 X、程序集 A 和程序集 B。程序集 A 引用了程序集 B,因此项目 X 包含对 A 和 B 的引用。此外,项目 X 包含引用程序集 A 的代码(例如 A. SomeFunction())。现在,您创建一个引用项目 X 的新项目 Y。
So the dependency chain looks like this: Y => X => A => B
所以依赖链看起来像这样:Y => X => A => B
Visual Studio / MSBuild tries to be smart and only bring references over into project Y that it detects as being required by project X; it does this to avoid reference pollution in project Y. The problem is, since project X doesn't actually contain any code that explicitly uses assembly B (e.g. B.SomeFunction()), VS/MSBuild doesn't detect that B is required by X, and thus doesn't copy it over into project Y's bin directory; it only copies the X and A assemblies.
Visual Studio / MSBuild 试图变得聪明,只将引用引入到项目 Y 中,它检测到项目 X 需要它;它这样做是为了避免项目 Y 中的引用污染。问题是,由于项目 X 实际上不包含任何显式使用程序集 B 的代码(例如 B.SomeFunction()),VS/MSBuild 没有检测到 B 是必需的通过 X,因此不会将其复制到项目 Y 的 bin 目录中;它只复制 X 和 A 程序集。
Solution
解决方案
You have two options to solve this problem, both of which will result in assembly B being copied to project Y's bin directory:
您有两种选择来解决这个问题,这两种选择都会导致程序集 B 被复制到项目 Y 的 bin 目录中:
- Add a reference to assembly B in project Y.
- Add dummy code to a file in project X that uses assembly B.
- 在项目 Y 中添加对程序集 B 的引用。
- 将虚拟代码添加到使用程序集 B 的项目 X 中的文件中。
Personally I prefer option 2 for a couple reasons.
我个人更喜欢选项 2,原因有几个。
- 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.
- 如果您将来添加另一个引用项目 X 的项目,您将不必记住还包含对程序集 B 的引用(就像您必须使用选项 1 那样)。
- 您可以有明确的评论,说明为什么需要存在虚拟代码而不是将其删除。因此,如果有人不小心删除了代码(比如使用查找未使用代码的重构工具),您可以很容易地从源代码管理中看到代码是必需的,并可以恢复它。如果您使用选项 1 并且有人使用重构工具来清理未使用的引用,则您没有任何评论;您只会看到从 .csproj 文件中删除了一个引用。
Here is a sample of the "dummy code" that I typically add when I encounter this situation.
这是我在遇到这种情况时通常添加的“虚拟代码”示例。
// 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);
}
回答by andrew
I just deal with it like this. Go to the properties of your reference and do this:
我就是这样处理的。转到参考的属性并执行以下操作:
Set "Copy local = false"
Save
Set "Copy local = true"
Save
and that's it.
就是这样。
Visual Studio 2010 doesn't initially put:
<private>True</private>in the reference tag and setting "copy local" to false causes it to create the tag. Afterwards it will set it to true and false accordingly.
Visual Studio 2010 最初不会放置:
<private>True</private>在引用标记中并将“复制本地”设置为 false 会导致它创建标记。之后它将相应地将其设置为 true 和 false。
回答by John Hunter
If you are not using the assembly directly in code then Visual Studio whilst trying to be helpful detects that it is not used and doesn't include it in the output. I'm not sure why you are seeing different behaviour between Visual Studio and MSBuild. You could try setting the build output to diagnostic for both and compare the results see where it diverges.
如果您没有直接在代码中使用程序集,那么 Visual Studio 在尝试提供帮助时会检测到它未被使用并且不会将其包含在输出中。我不确定为什么您会在 Visual Studio 和 MSBuild 之间看到不同的行为。您可以尝试将两者的构建输出设置为诊断并比较结果,看看它的分歧之处。
As for your elmah.dll reference if you are not referencing it directly in code you could add it as an item to your project and set the Build Action to Contentand the Copy to Output Directory to Always.
至于你的 elmah.dll 引用,如果你没有在代码中直接引用它,你可以将它作为一个项目添加到你的项目中,并将构建操作设置为Content并将复制到输出目录设置为Always。
回答by toebens
Take a look at:
看一眼:
This MSBuild forum thread I started
You will find my temporary solution / workaround there!
您会在那里找到我的临时解决方案/解决方法!
(MyBaseProject needs some code that is referencing some classes (whatever) from the elmah.dll for elmah.dll being copied to MyWebProject1's bin!)
(MyBaseProject 需要一些代码来引用 elmah.dll 中的某些类(无论如何),以便将 elmah.dll 复制到 MyWebProject1 的 bin 中!)
回答by Andre Avelar
I had the same problem.
我有同样的问题。
Check if the framework version of your project is the same of the framework version of the dll that you put on reference.
检查您的项目的框架版本是否与您引用的 dll 的框架版本相同。
In my case, my client was compiled using "Framework 4 Client" and the DLL was in "Framework 4".
就我而言,我的客户端是使用“Framework 4 Client”编译的,DLL 位于“Framework 4”中。
回答by vangorra
The issue I was facing was I have a project that is dependent on a library project. In order to build I was following these steps:
我面临的问题是我有一个依赖于库项目的项目。为了构建,我遵循以下步骤:
msbuild.exe myproject.vbproj /T:Rebuild
msbuild.exe myproject.vbproj /T:Package
That of course meant I was missing my library's dll files in bin and most importantly in the package zip file. I found this works perfectly:
这当然意味着我在 bin 中丢失了我的库的 dll 文件,最重要的是在包 zip 文件中。我发现这很有效:
msbuild.exe myproject.vbproj /T:Rebuild;Package
I have no idea why this work or why it didn't in the first place. But hope that helps.
我不知道为什么这项工作或为什么它首先没有。但希望有帮助。
回答by Steven Engels
I just had the exact same problem and it turned out to be caused by the fact that 2 projects in the same solution were referencing a different version of the 3rd party library.
我只是遇到了完全相同的问题,结果证明是由于同一解决方案中的 2 个项目引用了 3rd 方库的不同版本。
Once I corrected all the references everything worked perfectly.
一旦我更正了所有参考资料,一切都完美无缺。
回答by Scott
As Alex Burtsev mentioned in a comment anything that's only used in a XAML resource dictionary, or in my case, anything that's only used in XAML and not in code behind, isn't deemed to be 'in use' by MSBuild.
正如 Alex Burtsev 在评论中提到的,任何只在 XAML 资源字典中使用的东西,或者在我的例子中,任何只在 XAML 中使用而不是在代码背后使用的东西,都不会被 MSBuild 视为“正在使用”。
So simply new-ing up a dummy reference to a class/component in the assembly in some code behind was enough convince MSBuild that the assembly was actually in use.
因此,只需在后面的某些代码中新建对程序集中的类/组件的虚拟引用,就足以让 MSBuild 相信该程序集已在实际使用中。
回答by J Z
Using deadlydog's scheme,
使用deadlydog的方案,
Y => X => A => B,
Y => X => A => B,
my problem was when I built Y, the assemblies (A and B, all 15 of them) from X were not showing up in Y's bin folder.
我的问题是当我构建 Y 时,来自 X 的程序集(A 和 B,全部 15 个)没有出现在 Y 的 bin 文件夹中。
I got it resolved by removing the reference X from Y, save, build, then re-add X reference (a project reference), and save, build, and A and B started showing up in Y's bin folder.
我通过从 Y 中删除引用 X,保存,构建,然后重新添加 X 引用(项目引用),然后保存、构建和 A 和 B 开始出现在 Y 的 bin 文件夹中来解决它。
回答by Fuyu Persimmon
Changing the target framework from .NET Framework 4 Client Profileto .NET Framework 4fixed this problem for me.
将目标框架从.NET Framework 4 Client Profile更改为.NET Framework 4为我解决了这个问题。
So in your example: set the target framework on MyWebProject1 to .NET Framework 4
所以在你的例子中:将 MyWebProject1 上的目标框架设置为.NET Framework 4

