0

I have a project that seems to always be targeting x86/32 bit and I can't find out why. I have gone through all the projects in solution and made sure the PlatformTarget is AnyCPU.

Using dumpbin to examine all the binaries I get '14C machine (x86)'.

The build machine is x64 although previously was x86.

What else could be causing this and what should I check?

Craig
  • 36,306
  • 34
  • 114
  • 197
  • Are you doing any platform-specific P/Invoke? What is the build machine - x86 or x64? – Marc Gravell Aug 07 '11 at 12:27
  • No platform specific P/Invoke that I know about. – Craig Aug 07 '11 at 12:39
  • If you look at the .csproj (or .vbproj file) in a text editor, do the Compile targets look sensible, compared to a fresh project created in Visual Studio? Or do they look strange? – Erik A. Brandstadmoen Aug 07 '11 at 12:41
  • Any interesting references? Maybe one of the refs is x86 targeted... – Marc Gravell Aug 07 '11 at 12:47
  • No interesting references, mainly NHibernate, DevEx Reports & SharpArch, and all the various dependencies of them. I do notice all the third party references, such as NHibernate say '14 machine (x86)' as well, even though I didn't build them. – Craig Aug 07 '11 at 13:04
  • Nothing appears out of wack in the project files. – Craig Aug 07 '11 at 13:06
  • Are you using SQLite with NHibernate? I know SQLite is not a .NET (managed) DLL, so it is compiled for a specific architecture. See e.g. http://isay.monogra.fi/post/454778865/using-sqlite-with-nhibernate-on-64-bit-windows – Erik A. Brandstadmoen Aug 07 '11 at 13:09
  • When you run on x64 it runs as 32 bit? Did you check that? – David Heffernan Aug 07 '11 at 15:01

1 Answers1

4

You must be talking about the output you see from Dumpbin.exe with the /headers option. Which looks like this when run on a .NET assembly that's compiled with the platform target set to AnyCPU:

Dump of file ConsoleApplication1.exe

PE signature found

File Type: EXECUTABLE IMAGE

FILE HEADER VALUES
             14C machine (x86)
               3 number of sections
        4E3E987F time date stamp Sun Aug 07 08:51:59 2011
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
             102 characteristics
                   Executable
                   32 bit word machine
etc..

Yes, the IMAGE_FILE_HEADER.Machine value is set to 0x14c, the value of IMAGE_FILE_MACHINE_I386 (aka x86). This is of no consequence, perhaps the strongest hint that it is not relevant is the target name: AnyCPU. It runs as well on an x86 as on an x64 operating system.

What you really want to use is corflags.exe, it shows you the COR header in the file:

Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32
CorFlags  : 1
ILONLY    : 1
32BIT     : 0
Signed    : 0

The 32BIT flag is the important one, 0 indicates that AnyCPU was used. ILONLY = 1 indicates that the assembly contains IL only, no machine code. It will be 0 when you create assemblies with the C++/CLI language.

You can create an image file with the machine set to x64. I think that was introduced in .NET 3.0 (aka .NET 2.0 SP1). If you set the platform target to x64 then the machine type field will be set to IMAGE_FILE_MACHINE_AMD64 (aka x64). That doesn't make much difference, other than that the program will never run on a 32-bit operating system and that the main thread will get started with a 4 megabyte stack instead of a 1 MB stack.

The magic that turns a 32-bit executable image into a 64-bit process is described in this answer.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536