Figure out the bitness of a process and the ProcessorArchicture of the system


A process may run as native 32 bit process, native 64 bit process, or 32 bit process on 64 bit OS (WOW).


Some times you need to figure out the bitness of your process.


For example, fusion needs to know this information when you install an assembly to GAC. It is illegal to install a 64 bit assembly in a 32 bit OS. But if fusion is running under WOW, then it becomes legal as long as the 64 bit assembly has the same processorArchitecture as the machine.


You can use GetSystemInfo API to retrieve information about the system where the process is running.


GetSystemInfo returns a SYSTEM_INFO struct. SYSTEM_INFO.wProcessorArchitecture is the system’s processor architecture.


If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_IA64 or PROCESSOR_ARCHITECTURE_AMD64, then you know the process is running as a native 64 bit process.


If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_INTEL, the process is a 32 bit process. But it could be a native 32 bit process on 64 bit OS, or a WoW process. To figure out if the process is running under WoW, you can use the API IsWow64Process.


If the process is running under WoW, you need to call GetNativeSystemInfo to retrieve the real system processor architecture.


The whole process looks like this:


SYSTEM_INFO info = {0};
GetSystemInfo(&info);
if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
 printf(“Native 64 bit process on IA64”);
}
else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)) {
 printf(“Native 64 bit process on AMD64”);
}
else if (info.wProcessorArchitecture == PROCESS_ARCHITECTURE_INTEL)) {
 BOOL bIsWow = FALSE;;
 if (!IsWow64Process(GetCurrentProcess(), &bIsWow)){
   printf(“IsWow64Process failed with last error %d.”, GetLastError());
 }

 else
if (bIsWow) {
  GetNativeSystemInfo(&info);
  if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
   printf(“32 bit process on IA64”);
  }
  else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)) {
   printf(“32 bit process on AMD64”);
  }
  else {
   printf(“I am running in the future!”);
  }

 }
 else {
  printf(“Native 32 bit process on x86”);
 }
}
else {
  printf(“I am running in the future!”);
}


IsWow64Process and GetNativeSystemInfo only exists in XP+. If your application wants to run in downlevel you need to call LoadLibrary and GetProcAddress. See MSDN document for more detail.

Comments (7)

  1. Yaytay says:

    That’s a recipe for locking yourself into the current architectures – you should check for PROCESSOR_ARCHITECTURE_INTEL in case wProcessorArchitecture is either PROCESSOR_ARCHITECTURE_UNKNOWN or something else entirely.

    Also, according to MSDN IsWow64Process takes two arguments and has an error return value.

    Finally, to maintain support for older systems MSDN recommends that LoadLibrary/GetProcAddress be used to prepare IsWow64Process.

  2. Hasani says:

    could I get away with just using the IntPtr.Size property?

  3. junfeng says:

    Yaytay,

    I was just intend to show how to do it in principal. But you are absolutely right. Samples should be right. I’ll fix it.

    Hasani,

    The size of the pointer can tell you whether you are running 32 bit or 64 bit. But it does not tell you which processor you system has.

  4. Yaytay says:

    That’s still not there, if there is a new 64 bit processor and you are using WoW it won’t say anything 🙂

    Given the complexity of getting this right, maybe something should be added to the .net libraries.

    I have a bee in my bonnet about code samples being perfect – way too many people just copy them and use them.

    The alternative is to demonstrate using pseudo code, then you can get away with anything.

  5. junfeng says:

    forward thinking, I like that:)

  6. Glenn Pierce says:

    Hi Irecentlyreadyourarticle on the advantages of netmodules (http://blogs.msdn.com/junfeng/archive/2005/02/12/371683.aspx

    and noticed that you said he .Net framework 2.0 link.exe can produce a single file assembly and that Assemblies can contain one or more files. I wondered if .Netversion 2.0 would allow linking unmanaged code into a single file assembly. So I would not have to distribute a separate umanaged dll to Pinvoke into ?

    Sorry if this is noton the topicof the post I could not find any other means of contact.

    Thanks.

    My work email is pierce@gci.ac.uk

  7. junfeng says:

    Gleen Pierce,

    Yes, it is possible. Just link the unmanaged obj files together with the managed netmodules.