在x64和x86环境中使用PresentationCore和WindowsBase dll
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,但失败了。
现在,我对此有点困惑...
- 其他 .NET Framework dll 似乎可以在 x64 和 x86 版本之间无缝切换(分别从 Microsoft.NET/Framework64 或 Microsoft.NET/Framework 加载)。为什么PresentationCore 和WindowsBase 有什么不同?
- 为什么 Visual Studio 在“添加引用”对话框的“.NET”选项卡下似乎只提供 32 位版本?如果我想要 64 位版本,我必须“浏览”它。
- 是否有任何简单的方法可以自动选择正确的 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...
- 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?
- 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.
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可以有条件地引用与您的活动构建配置匹配的每个 .dll 文件。您需要手动编辑项目文件。添加对 32 位 DLL 的引用。然后保存项目并在文本编辑器中编辑 .csproj 文件。
搜索您添加的引用,并将 Condition="$(Platform) == 'x86'" 添加为 Reference 元素上的属性。然后制作参考元素的另一个副本并针对 x64 版本进行调整。以下是 Oracle ODP.NET 驱动程序的示例:
需要注意的一件重要事情是您将无法再使用“AnyCPU”配置。您需要有 x86 或 x64 的显式构建配置。您尝试使用的 .dll 可能会对操作系统库进行本机调用,因此您的项目不再与平台无关。
如果您只想维护 1 个构建配置,则可以使用 x86 并仅使用 x86/32 位版本。如果是 Web 应用程序,则需要将应用程序池设置为 32 位模式。
编辑以回答您最初的问题
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:
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