Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当程序集不应为';不可能_C#_Visual Studio 2010 - Fatal编程技术网

C# 当程序集不应为';不可能

C# 当程序集不应为';不可能,c#,visual-studio-2010,C#,Visual Studio 2010,这是我的示例场景。我有一个控制台应用程序和一个类库dll(称为libraryA)。LibraryA dll引用了Oracle.DataAccess.dll版本4.112.2.0。Oracle DLL位于GAC中。LibraryA中对Oracle DLL的引用是“Copy Local=false”。到目前为止还不错。如果构建libraryA dll,则Oracle.DataAccess.dll不会显示在其输出目录中。好啊现在,我在控制台应用程序中引用libraryA dll。对libraryA d

这是我的示例场景。我有一个控制台应用程序和一个类库dll(称为libraryA)。LibraryA dll引用了Oracle.DataAccess.dll版本4.112.2.0。Oracle DLL位于GAC中。LibraryA中对Oracle DLL的引用是“Copy Local=false”。到目前为止还不错。如果构建libraryA dll,则Oracle.DataAccess.dll不会显示在其输出目录中。好啊现在,我在控制台应用程序中引用libraryA dll。对libraryA dll的引用是“copy local=true”。现在,当我构建控制台应用程序时,Oracle.DataAcess.dll确实显示在控制台应用程序的输出目录中。但是,似乎唯一以这种方式运行的DLL是Oracle DLL。这是图书馆的完整代码

public void Foo() {            
   Oracle.DataAccess.Client.OracleConnection c = new Oracle.DataAccess.Client.OracleConnection();
   WebMatrix.WebData.OAuthAccountData x = new WebMatrix.WebData.OAuthAccountData("asd", "asd");            
   DevExpress.Web.ASPxCallback.ASPxCallback cvv = new DevExpress.Web.ASPxCallback.ASPxCallback();
}
WebMatrix和DevExpress也与Oracle DLL一样位于GAC中。但是,这些dll都不会输出到输出目录,只有Oracle dll。为什么?这里发生了什么事

为此,您可以创建另一个类库,称之为libraryB,不要将libraryB放在GAC中,从LibraryA引用libraryB并将copy local=false。即使这样做,libraryB也不会复制到console应用程序的输出目录。当然,在本例中,程序崩溃是因为它找不到库B,但至少VisualStudio使用了copy local标志=false。这个愚蠢的Oracle DLL有什么不同

哦,还有一件事很有趣。如果在控制台应用程序中,我显式地添加了对Oracle.DataAccess.dll的引用,并说copy local=false,那么它不会显示在输出目录中。要想在输出目录中不显示DLL,我必须实际引用它,这似乎有点可笑:)

编辑:

另一个线索。为了折磨开发人员,Oracle没有为任何CPU构建一个DLL。他们有x86和x64版本。在我的例子中,我引用了一个x86版本并构建了AnyCPU。但是,如果我为x86构建(以匹配oracle dll),则oracle dll不会复制到输出目录。在AnyCPU中构建时,MSBUILD表示:
警告MSB3270:正在生成的项目的处理器体系结构“MSIL”与参考“Oracle.DataAccess,版本=4.112.2.0,区域性=中性,PublicKeyToken=89b483f429c47342,processorArchitecture=x86”,“x86”的处理器体系结构不匹配“。此不匹配可能导致运行时失败。请考虑通过配置管理器更改项目的目标处理器体系结构,以便在项目和引用之间对齐处理器体系结构,或者依赖于与您项目的目标处理器体系结构相匹配的处理器体系结构的引用。“因此,看起来Msbuild最终决定了,好吧,您有一个不匹配项,所以让我继续将此dll复制到您的输出目录,从而保证您的应用程序将崩溃。”

不引用它,就是让它使用隐式规则。嗯,这里的默认值是“复制本地”,因为大多数DLL不在GAC中。IDE有一个疯狂的想法,默认为“让它工作”,这意味着“假设它不会出现在GAC中”


如果你想使用明确的规则,那么是的:你需要告诉它你想要什么。这样做的方法是添加一个引用,然后设置所需的选项。

在对我所研究的解决方案中的问题进行了大量调查之后,我们发现这个问题似乎是由.NET 4.5版本引入的一个新检查引起的,如前所述:在构建时,现在正在检查引用,以确保它们的处理器类型与项目的处理器类型匹配

虽然之前我们在构建日志中没有看到任何此类错误,但在受影响的计算机上,我们现在看到一条消息,表明项目是为MSIL构建的,DLL是为x86构建的-而不是为所有CPU提供一个构建的DLL,第三方创建者为x86和x64提供了两个单独的DLL,这两个DLL都在我们的GAC中。在引入此检查之前,系统将使用GAC中的DLL并选择适当的版本,但在安装.NET 4.5之后,构建过程似乎确定GAC中的两个版本都不可接受,因此它将引入本地副本


我们还无法确定任何方法来禁用此行为,因此我们的解决方案选项必须是,要么添加生成后事件以删除本地副本,要么(如问题中所述)将对问题DLL的引用添加到引用“库a”的所有项目中,然后将这些引用设置为“复制本地=错误,这似乎也会阻止将非工作的本地版本复制到输出中。

好的,但是为什么我引用的其他DLL的工作方式不同呢?此外,IDE不会试图使其与GAC中不存在的DLL一起工作。例如,如果我从库A引用库B,并且没有copy local=false,则库B不会被复制。为什么这个oracle(只有这个oracle)DLL?它取决于几件事:你是直接引用它吗?还是间接地?它在本地机器上的GAC中吗?还是不?特别是,过去(现在可能仍然)存在一个微妙的IDE故障,其中copy local实际上是三态:“true”、“false”或“未显式给定值”——这意味着您实际上可以为“false”获得不同的结果:如果最初为“false”,则默认情况下可能为“false”,其行为可能与“显式false”不同,如“默认情况下为false”实际上是对GAC的检查。我直接在LibraryA中引用它。我直接从ConsoleApplication1中引用LibraryA。在我构建时,DLL位于本地计算机上的GAC中。但是,我尝试从GAC中删除它,但没有任何区别。同样,这也会导致