在x64和x86环境中使用PresentationCore和WindowsBase dll

Dav*_*lls 5 .net asp.net msbuild dll 32bit-64bit

PresentationCore.dll和WindowsBase.dll都包含在Microsoft .NET Framework 3.0中,每个dll的两个版本都安装到磁盘:

  • C:\ Program Files\Reference Assemblies\Microsoft\Framework\v3.0下的x64版本
  • C:\ Program Files(x86)\ Reference Assemblies\Microsoft\Framework\v3.0下的x86版本

在添加对这些dll的引用之前,我们的ASP.NET Web应用程序能够针对"任何CPU"进行编译,并且可以在32位或64位模式下运行而不会出现问题.通过标准的"添加引用"对话框(添加引用 - > .NET - > PresentationCore)向PresentationCore添加引用后,Web应用程序在64位模式下失败,并出现以下错误:

无法加载文件或程序集"PresentationCore"或其依赖项之一.尝试加载格式不正确的程序.

显然这是因为64位应用程序池正在尝试加载32位版本的PresentationCore dll并且失败.

现在,我对此有点困惑......

  1. 其他.NET Framework dll似乎无缝地在x64和x86版本之间切换(分别从Microsoft.NET/Framework64或Microsoft.NET/Framework加载).为什么PresentationCore和WindowsBase有什么不同?
  2. 为什么Visual Studio似乎只在"添加引用"对话框的".NET"选项卡下提供32位版本?如果我想要64位版本,我必须"浏览"它.
  3. 是否有任何简单的方法可以自动选择正确的dll,就像其他.NET Framework库一样?

我们总是可以编写一些MSBuild xml,它会在构建时根据目标环境的位数自动交换引用,但这似乎是我们不应该为.NET Framework dll做的事情.是什么赋予了?

谢谢!

sco*_*732 3

可以有条件地引用与您的活动构建配置匹配的每个 .dll 文件。您需要手动编辑项目文件。添加对 32 位 DLL 的引用。然后保存项目并在文本编辑器中编辑 .csproj 文件。

搜索您添加的引用,并将 Condition="$(Platform) == 'x86'" 添加为 Reference 元素上的属性。然后制作参考元素的另一个副本并针对 x64 版本进行调整。以下是 Oracle ODP.NET 驱动程序的示例:

<Reference Include="Oracle.DataAccess, Version=2.111.6.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=AMD64" Condition="$(Platform) == 'x64'">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>lib\x64\Oracle.DataAccess.dll</HintPath>
  <Private>True</Private>
</Reference>
<Reference Include="Oracle.DataAccess, Version=2.111.6.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86" Condition="$(Platform) == 'x86'">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>lib\x86\Oracle.DataAccess.dll</HintPath>
  <Private>True</Private>
</Reference>
Run Code Online (Sandbox Code Playgroud)

需要注意的一件重要事情是您将无法再使用“AnyCPU”配置。您需要有 x86 或 x64 的显式构建配置。您尝试使用的 .dll 可能会对操作系统库进行本机调用,因此您的项目不再与平台无关。

如果您只想维护 1 个构建配置,则可以使用 x86 并仅使用 x86/32 位版本。如果是 Web 应用程序,则需要将应用程序池设置为 32 位模式。

编辑以回答您最初的问题

  • 当您构建 dll/可执行文件时,您有几个平台选项:任何 CPU、x86、x64 或 Itanium。100% 用托管代码编写且不依赖于本机库的代码通常作为 AnyCPU 进行编译和分发。这是因为编译器生成的中间语言 (IL) 代码可以在 x86、x64 和 Itanium 版本的 .NET Framework 上运行。可以从特定于平台(x86、x64、IA64)的应用程序安全地引用面向任何 CPU 的库。PresentationCore 和 WindowsBase 不同的原因是它们对本机代码有依赖性。与在运行时解释的 IL 代码不同,本机代码中没有 Any CPU 的概念。由于本机代码依赖性,PresentationCore 和 WindowsBase .NET 库需要作为 x86 和 x64 分发,因为 AnyCPU 是不可能的。
  • “添加引用”对话框应仅显示与您的目标平台兼容的库。如果您的目标平台是 x86,它应该只显示任何 CPU 和 x86 库。
  • 很不幸的是,不行。如果您无法使用任何 CPU,但仍需要支持 x86 和 x64,那么您需要设置多个构建配置(一种用于 x86,一种用于 x64),并有条件地引用您需要的 32 位和 64 位 dll。我知道执行此操作的唯一方法是编辑项目文件,如上所述。您将需要构建这两种配置并分发单独的 32 位和 64 位版本的代码。如果有人依赖您的代码,他们将需要经历同样的困难。