【问题标题】:How to force .NET application to run in 32bit mode如何强制 .NET 应用程序以 32 位模式运行
【发布时间】:2011-09-25 06:28:10
【问题描述】:

我正在尝试在 Win7 x64 上运行我的 .NET 3.5 WinForms 应用程序。该应用程序使用 NHibernate 和 System.Data.OracleClient 来访问 Oracle 数据库。 Oracle 客户端是 32 位的。

启动应用程序时,我收到以下错误消息

尝试加载 Oracle 客户端库引发了 BadImageFormatException。 在安装了 32 位 Oracle 客户端组件的 64 位模式下运行时会出现此问题。

作为回应,我将我的构建定位到 x86 平台:

令我惊讶的是,当尝试在 Win7 平台上执行新构建时,出现了完全相同的错误消息

NHibernate 程序集在运行时由Assembly.Load("..."); 加载。

可能是 NHibernate DLL 仍以 64 位模式运行,而主机 exe 以 32 位模式运行。这对我来说听起来很奇怪。还是因为任何原因,我的应用程序运行在 64 位模式下,即使它是针对 x86 的?


更新:

我使用 CorFlags 检查了我的二进制文件,它被标记为 32 位:

Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 3
ILONLY    : 1
32BIT     : 1
Signed    : 0

我也在任务管理器中查看过,它有一个*32 后缀。

我还尝试并使用 CorFlags 将 32 位标志添加到我的应用程序附带的 all 程序集中。它仍然会产生相同的错误消息。

我很困惑...很困惑...很困惑...

【问题讨论】:

  • 您是否通过任务管理器检查过您的程序在崩溃时是在 32 位还是 64 位模式下运行的?如果它的进程名称后面有“*32”,则它是 32 位的,否则是 64 位的(假设是 64 位操作系统和系统。)
  • 那么您针对 x86 的目标是什么?你的类库?你的程序?两者都有?
  • @Lasse:更详细地说,该应用程序由 3 层、2 个 DLL 和 1 个 EXE 组成,而一个 DLL 引用 NHibernate。我已将所有这些都针对 x86,并确保 EXE 项目在编译时使用 DLL 项目的 x86 箱。我唯一无法控制的是 NHibernate DLL 本身。
  • 您确定 NHibernate 程序集是 Any CPU,而不是 64 位?
  • @Lasse:是的,因为该应用程序在 Windows XP 32 位上运行流畅。我可能不得不尝试下载源代码并自行编译,但这会使构建和部署过程变得更加复杂,而且我很难相信加载到 EXE 进程中的程序集可以在不同的模式下运行比EXE本身。但是,我不是 .NET 深度的专家……

标签: .net-3.5 x86 64-bit corflags


【解决方案1】:

32 位进程无法加载 64 位 DLL,反之亦然(有关详细信息,请参阅 this)。这意味着如果您的进程成功加载了 64 位 DLL,那么它肯定是 64 位进程。您可以在任务管理器中验证这一点(如 Lasse 建议的那样)或通过here 所述的其他方式进行验证。该文章还包含有关 Windows x64 上 .Net 的更多信息。

【讨论】:

  • 您好 Helge,感谢您的回复。这也是我所估计的(DLL 必须以与其宿主进程相同的模式运行)。我检查了任务管理器并使用 CorFlags,我的 EXE 是 32 位的。 (请参阅我的问题的更新)。
【解决方案2】:

正确,听起来 NHibernate 程序集是使用 AnyCPU 作为其平台目标构建的。您需要专门为 x86 构建的 NHibernate 程序集。

【讨论】:

  • 嗨,六个字母的变量。这是否意味着当 EXE 在 32 位模式下运行时,加载到同一进程中的 DLL 仍然可以在 64 位模式下运行?你确定吗?这将是非常不幸的,因为我不控制 NHibernate 构建...
  • 不,正如我在回答中所写,32 位进程无法加载 64 位 DLL。
  • @Helge:我是说它加载了一个 AnyCPU DLL,然后请求了一个 64 位 DLL。
  • @sixlettervariables:我编译的EXE被标记为32bit。我认为 Helge 的观点是,由于它是 32 位的,NHibernate 也必须在 32 位模式下运行,即使它是为 AnyCPU 构建的。
  • @chiccodoro:在 x86 可执行文件上使用 Assembly.Load 和 AnyCPU DLL 的混合,我无法让任何测试应用程序以相同的方式出错。
【解决方案3】:

你可以试试RunAsx86

当从命令行运行它们时,我使用这个工具以 x86 模式启动 .NET 应用程序。

【讨论】:

    【解决方案4】:

    万一它对任何人有帮助,我在使用 Oracle 64 位和 Windows 7 64 位时遇到了相同的症状。我单独留下了平台目标(没有更改任何项目设置)。相反,我只是安装了 oracle 32 位并解决了这个问题。请务必更新您的环境变量(即 ORACLE_HOME、PATH)以指向 32 位版本。

    【讨论】:

    • 有趣的是,我遇到了 32 位的问题,最后安装 64 位解决了!
    【解决方案5】:

    我之前也遇到过类似的问题。我有一个使用 Crystal Reports 的 Windows 服务,在我的 64b 机器上一切都很好,我调整了一切——该项目是为使用 x86 架构而构建的。

    部署到不同机器时出现问题,服务失败,因为 Crystal Reports 引擎无法加载 log4net.dll 1.2.10 程序集。我检查了目录-那里的版本是1.2.11,我的本地目录包含相同的版本。 bindingRedirect 不起作用。

    然后我检查了 GAC - CR dll 已签名并由安装程序添加到 GAC,log4net 1.2.10 在那里,但处理器架构不是 x86。 在为x86 架构添加log4net 1.2.10 后,它就像一个魅力。

    【讨论】:

    • 我想分享我的故事,并表明这一切都是为了将​​正确的版本安装到 GAC。
    【解决方案6】:

    我在我的 c++ oracle 应用程序中遇到了同样的错误,我需要在 32 位机器上运行的 64 位机器上运行。错误的图像错误是由于 32 位和 64 位 dll 的混合造成的,所以我使用依赖walker 来查找混合了哪些 dll。在该应用程序中,我发现 oci.dll 是 64 位的,因为我安装了 64 位的 oracle 客户端,但所有其他 32 位的 dll。所以我在 64 位机器上安装了 32 位的 oracle 客户端并解决了这个错误。

    【讨论】:

      猜你喜欢
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      • 2013-06-06
      • 1970-01-01
      • 2013-04-20
      相关资源
      最近更新 更多