52

I have a .NET application that was supposed to be compiled as a 32-bit only application. I suspect my build server isn't actually doing it.

How do I determine if a .NET application is actually set to run in 32-bit mode?

Jonathan Allen
  • 68,373
  • 70
  • 259
  • 447
  • It's unclear what you're asking - do you have a dll that you want to check or an application that you want to check? – Jaco Pretorius Sep 23 '10 at 20:17
  • @jaco - it shouldn't matter. An exe is also an assembly. His main point is it needs to be done externally as the resultant program is the result of a build server. – x0n Sep 23 '10 at 20:18
  • True, but I'm trying to figure out what he's looking at. But you're right, it shouldn't matter. – Jaco Pretorius Sep 23 '10 at 20:23

8 Answers8

58

If you're trying to check whether or not a running application is running in 32-bit or 64-bit mode, open task manager and check whether or not it has an asterisk (*32) next to the name of the process.

EDIT (imported from answer by manna): As of Win8.1, the "bittyness" of a process is listed in a separate detail column labelled Platform. (Right click on any column header to expose the select columns menu.)

If you have a compiled dll and you want to check if it's compiled for 32-bit or 64-bit mode, do the following (from a related question). I would think that you want you dll to be compiled for AnyCPU.

Open Visual Studio Command Prompt and type "corflags [your assembly]". You'll get something like this:

c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC>corflags "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll"
    
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8 Copyright (c) Microsoft Corporation. All rights reserved.
    
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 24
ILONLY : 0
32BIT : 0
Signed : 1

You're looking at PE and 32BIT specifically.

AnyCpu:

PE: PE32 32BIT: 0

x86:

PE: PE32 32BIT: 1

x64:

PE: PE32+ 32BIT: 0

Uber Kluger
  • 394
  • 1
  • 11
Jaco Pretorius
  • 24,380
  • 11
  • 62
  • 94
  • 1
    Thanks, that is exactly what I wanted. (Though your answer also pisses me off a bit because I knew CorFlags could change the setting, but nothing in the docs tells me that it can also read it.) – Jonathan Allen Sep 23 '10 at 20:44
  • 2
    It's called the "Developer Command Prompt for VS" in VS 2017, by the way. (The name change makes it hard to find.) – jpmc26 Apr 06 '18 at 20:31
  • The instructions and output of corflags have changed. I don't want to edit this answer, so I posted a new one: https://stackoverflow.com/a/73744268/2279059 – Florian Winter Sep 16 '22 at 11:40
28

To do this at runtime...

You can evaluate IntPtr.Size. If IntPtr.Size == 4 then it's 32 bit (4 x 8). If IntPtr.Size == 8 then it's 64 bit (8 x 8)

Kevin McKelvin
  • 3,467
  • 1
  • 27
  • 27
12

Well, if you're using .NET 4.0, there's System.Environment.Is64BitProcess.

Dan Tao
  • 125,917
  • 54
  • 300
  • 447
  • 1
    I don't think this is answering the OP's question. – Will A Sep 23 '10 at 20:14
  • Isn't there some flag in the assembly that says whether to JIT it into 32, 64 or either? – Steven Sudit Sep 23 '10 at 20:14
  • @Will A: Couldn't the OP put that code in his app and cause it to display a message on loadup (or something)? It's an honest question -- I really thought this was what he wanted. Now that I see some of the other answers I realize maybe he wanted something outside the process itself, though. – Dan Tao Sep 23 '10 at 20:19
  • @Dan - fair point, Task Manager would be an easier means of determining, however, this does of course work - sorry Dan! – Will A Sep 23 '10 at 20:25
  • At runtime, doesn't checking `sizeof(IntPtr)` do it? (And, yes, I know that doesn't answer the OP's question, but it is relevant to Dan's answer.) – Jim Mischel Sep 23 '10 at 20:41
  • @Jim: I don't think `sizeof(IntPtr)` is legal. – Dan Tao Sep 23 '10 at 21:01
  • @Jim: I was wrong: looks like it's only legal in an `unsafe` context, though. – Dan Tao Sep 23 '10 at 21:02
7

The quickest way is probably that it'll have an asterisk (*) after its name in task manager when run on a 64 bit machine. The asterisk means it's running in syswow64, ergo it's marked 32 bit.

The other way is to run corflags.exe against it and this will display the answer you're after. This comes with the .NET SDK.

x0n
  • 51,312
  • 7
  • 89
  • 111
4

I use the following code:

[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process(
    [In] IntPtr hProcess,
    [Out] out bool wow64Process
);

With:

public static bool IsProcess64(Process process)
{
    if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6) {
        bool ret_val;

        try {
            if (!WindowsAPI.IsWow64Process(process.Handle,out ret_val)) ret_val = false;
        } catch {
            ret_val = false;
        }

        if (!ret_val && IntPtr.Size == 8) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

You can pass Process.CurrentProcess or similar to this.

Lloyd
  • 29,197
  • 4
  • 84
  • 98
  • This has some flaws, mostly related to exceptionhandling: the "catch-all-and-everything" clause will also catch things like OutOfMemoryException, ThreadAbortException, AccessViolationException, etc. all stuff that signals a bad state of the CLR and has nothing to do with the process in question not beeing a 32bit process on 64 bit system (WOW64). Then, the "Handle" property throws an exception if called for process with no permission or which is gone already - it could still be 32bit process. Finally, if IntPtr.Size is 64, the process is 64 bit - no more need for the other stuff to check then. – Christian.K Sep 24 '10 at 06:23
  • That is true I haven't changed this code in a long time. I should address all of those issues really. – Lloyd Sep 24 '10 at 08:18
2

If you want to test an assembly non programmatically, you can use corflags.exe

>corflags.exe <assembly>

<listing of header information, among them the 32bit-ness>
Vinko Vrsalovic
  • 330,807
  • 53
  • 334
  • 373
2

I was searching for the same information and I found that since Windows 8.1, there is no more asterisk.

You have a Task Manager details column named "Platform". Its content is "32 bits" or "64 bits".

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
manna
  • 188
  • 3
  • 7
2

This is an update of the old accepted answer from 2010:

  1. Open Visual Studio.
  2. Go to "Tools" --> "Command Line" --> "Developer Command Prompt".
  3. Run corflags <path/to/your/exe_or_dll_file>.

The output of corflags has changed and now looks like this:

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

The line to look for is 32BITREQ, which means "32-bit required". It is set to 1 if you build with Any CPU but also link against a 32-bit native DLL. This means your DLL or EXE is effectively "32-bit (only)", e.g., it cannot run in a 64-bit IIS application pool.

If a DLL was built with platform x64 rather than Any CPU, then the output may look like this:

Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32+
CorFlags  : 0x1
ILONLY    : 1
32BITREQ  : 0
32BITPREF : 0
Signed    : 0

The string PE+ indicates that the DLL was built for x64. With x86 or Any CPU, it is PE32.

Florian Winter
  • 4,750
  • 1
  • 44
  • 69