将间接引用的程序集复制到输出目录 - 程序集丢失
可能的重复:
本地复制如何工作?
我有以下情况:
- 有一个名为 OLAF 的项目。工具,并且该项目引用 C:\Program Files\SQLXML 4.0\bin\Microsoft.Data.SqlXml.dll 中的 Microsoft.Data.SqlXml。参考复制本地属性设置为 True。当我在 bin 目录中构建该项目时,我可以看到 OLAF.Tools.dll 和 Microsoft.Data.SqlXml.dll
- 有一个名为 OLAF.Generator 的控制台应用程序,并且该应用程序引用 OLAF.Tools (我已使用“项目”选项卡添加了引用)。当我在 bin 目录中构建该应用程序时,我只能看到 OLAF.Generator.exe 和 OLAF.Tools.dll - 没有 Microsoft.Data.SqlXml.dll,这让我感到惊讶。另一个奇怪的事情是,即使该 dll 丢失,应用程序也能正常执行。
所以我的问题是:
- 为什么 Microsoft.Data.SqlXml.dll 没有复制到 OLAF.Generator 控制台应用程序的 bin 文件夹中?
- 应用程序如何解析可以找到 Microsoft.Data.SqlXml.dll 的目录?
谢谢,Pawel
编辑1:(在Marc Gravell回复后)
@Marc Gravell:你的回答给了我深思熟虑的空间,因为我可以发誓我总是可以看到间接依赖主应用程序的 bin 目录中的程序集。恕我直言,我不同意你的观点 - 恕我直言:)
当然,引用在物理上并不是级联的(我们正在谈论与类、接口等的牢固关系) - 这正是我在构建时想要实现的目标OLAF.工具库。该库提供了一个抽象级别,它包含工厂,一个工厂接受参数字符串并返回接口。该接口的一种特定实现使用 Microsoft.Data.SqlXml 组件。因此, OLAF.Generator 使用位于 OLAF.Tools 中的接口,但不了解 Microsoft.Data.SqlXml 中的组件。
除此之外(我想我们都知道我在前一段中试图解释的内容),在构建应用程序时,应该复制依赖程序集(如果 Copy Local 设置为 TRUE)。我刚刚编写了示例应用程序,项目 B lib 引用了项目 A lib,项目 C(控制台应用程序)引用了项目 B。在项目 C 的 bin 目录中,我可以看到所有内容:Project A.dll、Project B.dll 和 Project B.dll。项目C.exe。因此,在讨论的场景中,Microsoft.Data.SqlXml 没有最终出现在 OLAF.Generator bin 文件夹中的原因与该程序集本身有关。
编译器/Visual Studio 是否知道 Microsoft.Data.SqlXml 位于自动探测的目录中(或者位于 GAC 中),这就是不复制该程序集的原因?
编辑2:我刚刚检查了GAC,确实,Microsoft.Data.SqlXml.dll 安装在GAC 中。
Possible Duplicate:
How does Copy-local work?
I have following situation:
- there's a project named OLAF.Tools, and that project references Microsoft.Data.SqlXml in C:\Program Files\SQLXML 4.0\bin\Microsoft.Data.SqlXml.dll. Reference Copy Local property is set to True. When I build that project in bin directory I can see both OLAF.Tools.dll and Microsoft.Data.SqlXml.dll
- there's a console application named OLAF.Generator, and that application references OLAF.Tools (I've added reference using Project tab). When I build that application in bin directory I can see only OLAF.Generator.exe and OLAF.Tools.dll - there's no Microsoft.Data.SqlXml.dll, what supprises me. Another wierd thing is that even though that dll is missing application is executing properly.
So my questions are:
- why Microsoft.Data.SqlXml.dll is not copied to bin folder of OLAF.Generator console application?
- how application resolves directory where Microsoft.Data.SqlXml.dll can be found?
Thanks,Pawel
EDIT 1: (after response from Marc Gravell)
@Marc Gravell: Your answer gave me food for thought, as I could swore that I could always see indirectly dependant assemblies in main application's bin directory. And IMHO I don't agree with you - with all due respect :)
Of course, references are not cascaded physically (we're are talking about strong relationship to classes, interfaces etc) - and it's exactly what I wanted to achieve when building OLAF.Tools library. That library provides a level of abstraction, it contains factories, and one factory accepts as a parameter string and returns interface. One particular implementation of that interface uses Microsoft.Data.SqlXml components. As a result,
OLAF.Generator uses interface that is located in OLAF.Tools, but doesn't know about components in Microsoft.Data.SqlXml.
Apart from that (I think we both know what I tried to explain in preceding paragraph), when building application, dependant assemblies should be copied (if Copy Local is set to TRUE). I just wrote sample application, Project B lib has reference to Project A lib, and Project C (console app) has reference to Project B. In Project C's bin directory I can see all: Project A.dll, Project B.dll & Project C.exe. So in discussed scenario, the reason why Microsoft.Data.SqlXml doesn't end up in OLAF.Generator bin folder has something to do with that assembly itself.
Does compiler/visual studio knows that Microsoft.Data.SqlXml is located in directory which is automatically probed (or it's in GAC) and this is the reason why that assembly is not copied?
EDIT 2: I've just checked GAC, and indeed, Microsoft.Data.SqlXml.dll is installed in GAC.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
引用不会自动级联,因此添加对 OLAF.Tools 的引用不会同时添加对 SQLXML 的引用。如果您想使用 exe 部署 SQLXML,那么最方便的方法是从 exe 显式添加对 SQLXML 的引用,并将其设置为复制本地。如果没有这个,它就不会被部署。基本上,开发人员有责任决定运行时实际需要哪些文件(这通常是所使用的引用的子集,并且取决于许多只有您才能知道的部署决策)。
关于它在运行时是如何解决的...探测路径有点黑艺术,主要意思是“应用程序文件夹”,但这取决于配置,实际上可以咨询 GAC。您还有机会通过 AppDomain.Current.AssemblyResolve 提供自己的解析器。
References are not automatically cascaded, so adding a reference to OLAF.Tools does not also add a reference to SQLXML. If you want to deploy SQLXML with your exe, then the most convenient way to do that is to explicitly add a reference to SQLXML from your exe, and set it to copy local. Without this, it is not deployed. Basically, the onus is on the developer to decide which files are actually needed at runtime (which is often a subset of the references used, and depends on a number of deployment decisions which only you can know).
Re how it is resolved at runtime... the probing paths are a bit of a black art, mainly meaning "the app folder", but it depends on the config, and indeed the GAC may be consulted. You also get an opportunity to provide your own resolver, via
AppDomain.Current.AssemblyResolve
.本地复制如何工作? log4net.dll 没有被复制到 MyProject 输出目录 - 这是我问题的答案。当库安装在 GAC 中时,即使使用 COPY LOCAL 设置,也不会复制它。
How does Copy-local work? log4net.dll is not being copied to MyProject output directory - this is answer to my question. When library is installed in GAC, it won't be copied even though COPY LOCAL setting is used.