12

I am trying to run my .NET 3.5 WinForms application on a Win7 x64. The application uses NHibernate and the System.Data.OracleClient to access an Oracle database. The Oracle client is 32bit.

When starting up the app I get the following error message

Attempt to load Oracle client libraries threw BadImageFormatException. This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.

In response to that, I targetted my build to the x86 platform:

Screenshot of the Build settings

To my surprise, the very same error message appeared when trying to execute that new build on the Win7 platform.

The NHibernate assembly is loaded at runtime by Assembly.Load("...");.

Could it be that the NHibernate DLL still runs in 64 bit mode whilst the host exe runs in 32 bit mode. That sounds strange to me. Or could it be that for whatever reason, my application runs in 64 bit mode even though it was targeted to x86?


Update:

I checked my binary using CorFlags, and it is marked 32 bit:

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

I also checked it in Task Manager, and it has a *32 suffix.

I also tried and used CorFlags to add the 32bit flag to all assemblies that come with my application. It still yields the same error message.

I'm puzzled... puzzled... puzzled...

Drew Gaynor
  • 7,733
  • 5
  • 36
  • 50
chiccodoro
  • 13,709
  • 16
  • 83
  • 129
  • 1
    Have you checked via task manager wether your program is running in 32-bit or 64-bit mode when it crashes? If it has "*32" behind its process name, it is 32-bit, otherwise 64-bit (assuming 64-bit OS and system.) – Lasse V. Karlsen Jun 29 '11 at 15:22
  • 2
    And what did you target to x86? Your class library? Your program? Both? – Lasse V. Karlsen Jun 29 '11 at 15:23
  • 1
    @Lasse: In more detail the application consists of 3 layers, 2 DLLs and 1 EXE, whereas one DLL references NHibernate. I have targetted all of these to x86, and made sure that the EXE project uses the x86 bins of the DLL projects when compiling. The only thing I can't control is the NHibernate DLL itself. – chiccodoro Jun 29 '11 at 15:33
  • Are you sure the NHibernate assemblies are Any CPU, and not 64-bit? – Lasse V. Karlsen Jun 29 '11 at 15:49
  • @Lasse: Yes, since the application runs smoothly on Windows XP 32 bit. I might have to try and download the source and compile it on my own, but that makes the build and deployment process a lot more complicated, and I can hardly believe that the assembly which is loaded into the EXE process can run in a different mode than the EXE itself. However, I'm not an expert in the depths of .NET... – chiccodoro Jun 29 '11 at 20:06

6 Answers6

6

32-bit processes cannot load 64-bit DLLs and vice versa (see this for details). That means that if your process successfully loaded a 64-bit DLL then it most definitely is a 64-bit process. You can verify that in Task Manager (as Lasse suggested) or via other means described here. That article also has more information on .Net on Windows x64.

Helge Klein
  • 8,577
  • 8
  • 44
  • 69
  • Hi Helge, thank you for the reply. That's what I would have reckoned, too (that DLL's must run in the same mode as their host process). I checked in Task Manager and using CorFlags, and my EXE is 32 bit. (See update to my question). – chiccodoro Jul 01 '11 at 12:19
3

Correct, it sounds like the NHibernate assembly is built with AnyCPU as its platform target. You'll need an NHibernate assembly that is built for x86 specifically.

user7116
  • 60,025
  • 16
  • 134
  • 166
  • Hi sixlettervariables. Does that mean that when an EXE runs in 32 bit mode, a DLL loaded into the same process can still run in 64 bit mode? Are you sure? That would be quite unfortunate since I do not control the NHibernate builds... – chiccodoro Jun 29 '11 at 15:35
  • No, as I wrote in my answer a 32-bit process cannot load 64-bit DLLs. – Helge Klein Jun 30 '11 at 10:44
  • @Helge: I'm saying it loaded an AnyCPU DLL, which then requested a 64-bit DLL. – user7116 Jun 30 '11 at 10:59
  • @sixlettervariables: The EXE that I compiled is marked as 32bit. I think Helge's point is that since it is 32bit, NHibernate must be running in 32bit mode, too, even though it was build for `AnyCPU`. – chiccodoro Jul 01 '11 at 12:28
  • @chiccodoro: I can't get any test apps to error in the same manner, using `Assembly.Load` and a mix of AnyCPU DLL's on a x86 executable. – user7116 Jul 01 '11 at 14:11
  • @sixlettervariables: Very strange, isn't it? Thank you very much for your efforts! We will see how to proceed with this issue. We are also trying to get an Oracle 64bit client running (in parallel with a 32 bit client) and have the application use that. Of course it is not satisfactory to leave this issue open. Maybe I'll come back to it at a later stage. – chiccodoro Jul 05 '11 at 07:19
2

You can try RunAsx86

I use this tool to start .NET applications in x86 mode, when run them from command line.

Alex H
  • 41
  • 4
0

In case it helps anybody, I was running into the same symptoms with Oracle 64 bit and Windows 7 64 bit. I left the platform target alone (did not change any project settings). Instead I simply installed oracle 32 bit and that resolved the issue. Be sure to update your environment variables (i.e. ORACLE_HOME, PATH) to point to the 32 bit version.

chiccodoro
  • 13,709
  • 16
  • 83
  • 129
n00b
  • 3,335
  • 3
  • 28
  • 54
0

I have run into similar problem before. I have a windows service using Crystal Reports, everything was fine on my 64b machine, I tuned everything - the project was built to use x86 architecture.

The problem occurred when deployed to different machine, the service was failing because the Crystal Reports engine could not load log4net.dll 1.2.10 assembly. I checked the directory - the version there was 1.2.11, my local directory contained the same version. The bindingRedirect did not work.

Then I checked GAC - CR dlls are signed and were added to GAC by installer, log4net 1.2.10 was there but the processor architecture was not x86. After adding the log4net 1.2.10 for x86 architecture it worked like a charm.

Karel Frajták
  • 4,409
  • 20
  • 33
0

I have got the same error in my c++ oracle application which i need to run on 64 bit machine build in 32 bit machine. the bad image error is due to intermixing of dlls of 32 bit and 64 bit so i used dependency walker to find which dlls are intermixed. In that application i found that oci.dll are of 64 bit as i have installed oracle client of 64 bit but all other dlls of 32 bit. so i installed the oracle client for 32 bit on 64 bit machine and resolved this error.

Heena Goyal
  • 386
  • 3
  • 17