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

发布于 2024-12-20 00:57:58 字数 1081 浏览 0 评论 0原文

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

  • 下的 x64 版本
  • C:\Program Files\Reference Assemblies\Microsoft\Framework\ v3.0 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 执行的操作。什么给?

谢谢!

PresentationCore.dll and WindowsBase.dll are both included with the Microsoft .NET Framework 3.0, and two versions of each dll are installed to disk:

  • An x64 version under C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0
  • An x86 version under C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0

Until adding references to these dlls, our ASP.NET web app was able to be compiled for "any CPU" and would run in either 32bit or 64bit mode with no issue. After adding a reference to, say, PresentationCore via the standard "Add Reference" dialog (Add Reference -> .NET -> PresentationCore), the web app fails when in 64bit mode with the following error:

Could not load file or assembly 'PresentationCore' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Clearly this is because the 64bit app pool is trying, and failing, to load a 32bit version of the PresentationCore dll.

Now, I'm a little confused by this...

  1. Other .NET Framework dlls seem to switch between their x64 and x86 version seamlessly (loading from Microsoft.NET/Framework64 or Microsoft.NET/Framework, respectively). Why are PresentationCore and WindowsBase any different?
  2. Why does Visual Studio appear to only offer me the 32-bit version under the ".NET" tab in the "Add Reference" dialog? If I want the 64bit version, I have to "Browse" for it.
  3. Is there any simple way to automatically have the correct dll selected, like seems to happen for other .NET Framework libraries?

We can always write a bit of MSBuild xml that will automatically swap references at build time based on the bitness of the target environment, but that seems like something we shouldn't have to do for .NET Framework dlls. What gives?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落叶缤纷 2024-12-27 00:57:58

可以有条件地引用与您的活动构建配置匹配的每个 .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>

需要注意的一件重要事情是您将无法再使用“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 位版本的代码。如果有人依赖您的代码,他们将需要经历同样的困难。

It is possible to conditionally reference each the .dll file that matches your active build configuration. You'll need to manually edit your project file. Add a reference to the 32-bit DLL. Then save the project and edit the .csproj file in a text editor.

Search for the reference that you added and add Condition="$(Platform) == 'x86'" as an attribute on the Reference element. Then make another copy of the Reference element and tweak it for the x64 version. Here's an example with the Oracle ODP.NET drivers:

<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>

One important thing to note is that you'll no longer be able to use the 'AnyCPU' configuration. You will need to have explicit build configurations for x86 or x64. The .dll you are trying to use is likely making native calls into OS libraries so your project can no longer be platform agnostic.

If you only want to maintain 1 build configuration, you can go with x86 and use only the x86/32-bit version. If it's a web application, you will need to put the app pool into 32-bit mode.

Edited to answer your original qeustions

  • You have a handful of platform options when you build a dll/executable: Any CPU, x86, x64, or Itanium. Code that is written 100% in managed code and has no dependencies on native libraries are generally compiled & distributed as AnyCPU. This is because the resulting intermediate language (IL) code generated by the compiler can run on the x86, x64, and Itanium versions of the .NET Framework. Libraries that target Any CPU can be referenced safely from applications that are platform specific (x86, x64, IA64). The reason that PresentationCore and WindowsBase are different is because they have dependencies on native code. Unlike IL-code, which is interpreted at runtime, there is no concept of Any CPU in native code. Because of the native code dependencies, the PresentationCore and WindowsBase .NET libraries needed to be distributed as x86 and x64, as AnyCPU is not possible.
  • The Add Reference dialog should only show you libraries that are compatible with the platform that you're targeting. If your Target Platform is x86, it should only show you Any CPU and x86 libraries.
  • Unfortunately, no. If you can't use Any CPU, but still need to support x86 and x64, then you need to setup multiple build configurations (one for x86 and one for x64) and conditionally reference the 32-bit and 64-bit dll's you need. The only way I know of to do this is to edit the project file as detailed above. You will need to build both configurations and distribute separate 32-bit and 64-bit versions of your code as well. If anyone depends on your code, they will need to jump through the same hoops.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文