Sdílet prostřednictvím


64 bit and managed code

This article covers some 64 bit aspects regarding managed code and COM+ applications. The 64 bit info regarding managed code was taken from Josh Williams' blog and I want to thank him for putting all this useful information online. Personally, I found his postings very usefull. The COM+ application info I was able to find it in the documentation for CoCreateInstanceEx and CLSCTX enumeration.

Josh's articles cover mostly the subject of porting managed code EXE apps to 64 bit. Here are some links that you will find very useful:

  1. Behavior of 1.0/1.1 managed apps on 64bit machines
  2. What is the WOW64 and what does it mean to managed apps that you run on 64bit machines?
  3. How the OS Loader will force .Net v1.0/1.1 executables to run under WOW64 on a 64-Bit Machine

If you don't have the patience to read these articles, here's my scaled down summary with explanations removed:

  • AMD64 - 64 bit processor designed by AMD, initially named X86-64. Intel has its own compatible processors under the names EM64T, IA-32e, or Intel 64. x86-64 and x64 names are used by vendors to refer to these processors.
  • IA64 - a 64-bit processor architecture developed cooperatively by Intel Corporation and Hewlett-Packard
  • Once a process is started up as either 32bit or 64bit all of the dlls/assemblies that are loaded into that process have to be compatible with that bitness. Incidently, the same is true about the .Net Framework version loaded in the process.
  • .Net 1.0 and .Net 1.1 EXE applications running on a 64 bit machine will run in 32-bit runtime in WOW64 mode. The selection of the .Net Framework (1.0, 1.1 or 2.0) will be determined by the CLR’s loader policy, just as it would be on a 32-bit box.
  • If you know that your .Net 1.0 or .Net 1.1 EXE app is safe to be run in 64 bit mode, you can run CorFlags.exe with the /UpgradeCLRHeader parameter on your EXE in order to upgrade the IMAGE_COR20_HEADER runtime version to 2.5 (version number for .Net Framework 2.0). This will make your EXE to run as 64 bit app on a 64 bit machine. A v1.0/1.1 image which has had its MinorRuntimeVersion whacked will still be compatible with the v1.0/1.1 runtimes.
  • .Net 1.0 and .Net 1.1 assemblies can be loaded and executed as 64 bit native into a 64 bit process. This can be done even without setting the IMAGE_COR20_HEADER runtime version to 2.5. If you make a .Net 2.0 executable and link against a v1.0/1.1 dll you will be able to load it into your process as if it was a .Net 2.0 MSIL assembly. If that v1.0/1.1 dll has code that isn’t safe to run in 64-bit mode it may crash.
  • .Net 2.0 when installed on a 64 bit machine it will also install the 32 bit version of the framework. .Net 2.0 32 bit version will be installed in \WINDOWS\Microsoft.Net\Framework just as it would on a native 32bit machine whereas the 64bit version ends up in \WINDOWS\Microsoft.Net\Framework64.
  • .Net 2.0 EXEs and DLLs have bitness information attached at compile time. CLR headers of your PE image can be marked with one of four things: MSIL, x86, x64, IA64 (names vary). You can chose how the assembly is being compiled, by default MSIL.
    • x86 EXE - runs fine on 32 bit, runs in WOW64 mode on 64 bit
    • x64 EXE - runs as 64 bit on x64 machines, raises BadImageException on anything else (including IA64)
    • IA64 EXE - runs as 64 bit on IA64 machine, raises BadImageException on anything else (including x64)
    • MSIL EXE (aka anycpu/neutral/agnostic) - the assembly is not processor specific. It runs as 32 bit on x86 machines, as 64 bit on x64 and IA64 machines.

The articles above, however do not cover the COM+ application case. Let's say I have an out-of-proc managed COM+ component. This component is implemented as a C# class derived from ServicedComponent with attribute ApplicationActivation set to ActivationOption.Server. The assembly containing this component was compiled using .Net 2.0 and it's marked as anycpu/MSIL. This means that the assembly and component are processor neutral and it can run as both 32 and 64 bit on a 64 bit machine. Because the server is out-of-proc, the client and server do not need to share the same bitness. The client can be 32 bit and the server 64 bit, or viceversa. This can be used successfully to integrate legacy 32 bit components into 64 bit applications. Here's an article named 64-bit Insider that covers this aspect.

When a client app instantiates this component, the COM+ component will be created in its own process. Will that process have the same bitness as the client, will it have the bitness determined by the COM+ application settings or by the managed code setting? This article https://windowssdk.msdn.microsoft.com/en-us/library/ms693716.aspx about CLSCTX (paramater to CoCreateInstance) shades some light on some of these aspects, so I included some of the information here. Here's my summary:

  • the client of the COM+ application can control the bitness of the server process by passing in CLSCTX_ACTIVATE_32_BIT_SERVER or CLSCTX_ACTIVATE_64_BIT_SERVER (when calling CoCreateInstanceEx).
  • the server COM+ component can have its own bitness setting. If the client passes in one of the values above, the client value will overide the server value.
  • If neither the client nor the server specifies a preference then
    • on Windows XP or Windows Server 2003 without SP1 - 64 bit will be tried first with fallback to 32 bit in case of failure
    • on Windows Server 2003 with SP1 or later - the server will match the client architecture first, and it will fallback to the alternative in case of failure

The table below taken from MSDN documentation shows the results of the various combinations of client architectures and client settings and server architectures and server settings.

I hope you found this information useful.

 

32-bit client, no flag

64-bit client, no flag

32-bit client, 32-bit flag1

32-bit client, 64-bit flag2

64-bit client, 32-bit flag1

64-bit client, 64-bit flag2

32-bit server, match client registry value3

32-bit server

F8

32-bit server

F8

32-bit server

F8

32-bit server, 32-bit registry value4

32-bit server

32-bit server

32-bit server

F8

32-bit server

F8

32-bit server, 64-bit registry value5

F8

F8

32-bit server

F8

32-bit server

F8

32-bit server, no registry value6

64/329

64/329

32-bit server

F8

32-bit server

F8

32-bit server, no registry value,

Windows Server 2003 SP17

32-bit server

64/329

32-bit server

F8

32-bit server

F8

64-bit server, match client registry value3

F8

64-bit server

F8

64-bit server

F8

64-bit server

64-bit server, 32-bit registry value4

F8

F8

F8

64-bit server

F8

64-bit server

64-bit server, 64-bit registry value5

64-bit server

64-bit server

F8

64-bit server

F8

64-bit server

64-bit server, no registry value6

64-bit server

64-bit server

F8

64-bit server

F8

64-bit server

64-bit server, no registry value, Windows Server 2003 SP17

32/6410

64-bit server

F8

64-bit server

F8

64-bit server

 

Additional useful information can also be found in the Serviced Components in 32-bit and 64-bit Architectures article. A COM application will either be 32 bit or 64 bit but it cannot be both. In order to register a 64 bit COM+ application for an assembly containing a serviced component you will have to run the 64 bit version of regsvcs tool. If you want the same serviced component to run as both 32 bit and 64 bit you will need to have 2 separate components sharing (inheriting) a common implementation, each serviced component with its own COM+ application for it.

1 CLSCTX_ACTIVATE_32_BIT_SERVER.

2 CLSCTX_ACTIVATE_64_BIT_SERVER.

3 PreferredServerBitness registry value = 1. See PreferredServerBitness.

4 PreferredServerBitness registry value = 2.

5 PreferredServerBitness registry value = 3.

6 PreferredServerBitness registry value is missing and Windows Server XP or Windows Server 2003 without SP 1 or later is installed.

7 PreferredServerBitness registry value is missing and Windows Server 2003 SP 1 or later is installed.

8 Fails with CO_CLASSNOTREG error.

9 A 64-bit server is activated if it exists; otherwise a 32-bit server is activated.

10 A 32-bit server is activated if it exists; otherwise a 64-bit server is activated.