Most of the 32 bit Windows programs would run successfully in 64 bit Windows (XP, Vista & above). But in some cases your 32 bit Windows program may fail on a 64 bit Windows operating system.
Here are some common cases, I have covered:
- You have a 32 bit DLL that is a COM plug-in to some of the standard Windows programs such as Windows Explorer, Internet Explorer, Shell Extension etc.
- You have a 32 bit system hook DLL which all the processes must load.
This article talks about building the DLL using Visual C++ 9.0 (Visual Studio 2008).
My development machine is Windows XP (32 bit). I assumed that in order to build 64 bit programs, one must compile the project on a 64 bit operating system. But this is not the case.
The good news is that you can build 64 bit programs on a Win32 OS also. However, you cannot debug the programs on Win32 OS. You will need Win64 OS to debug. My DLLs were pretty straight forward. So I built the DLLs on Win32 OS and tested them on Win64 OS.
Installing x64 Compilers
Visual Studio 2008 comes with x64 compilers. By default, they are deselected during installation. Install them from your CD if you haven’t done so.
Compiling 64 bit DLL/EXE
- Open your Visual C++ Solution
- Choose Build->Configuration Manager menu
- Inside the Configuration Manager window, change the ‘Active solution platform’ to x64. If you don’t have any, you would need to create one by selecting the ‘New..’ drop down item. Copy settings from your Win32 platform.
- Now rebuild your solution.
Typically, the output files are created under the folder \. Example: x64\Release or x64\Debug.
When compiling you might get some warnings/errors due to the change in platform. You may have to use INT_PTR instead of int. DWORD_PTR instead of DWORD. The return types for OnTimer function may need to be changed etc.
If you have any Win64 specific code, then use the _WIN64 macro to separate it from the Win32 code. At runtime, to check if the current operating system is 64 bit, call the function GetSystemWow64Directory. If it succeeds then it means that the operating system is 64 bit. Some developers suggest using the IsWow64Process function to detect the operating system type, but it is not recommended based on MSDN documentation.
Remember, you would need to link to 64 bit versions of any third party DLLs that you are using. The linker will automatically pick the 64 bit versions of the standard runtime DLLs such as MFC, ATL, CRT etc.
The VC++ Directories (Tools->Options->Projects and Solutions) are platform specific. So you will need to specify a different set of directories for your third party 64 bit DLLs.
Deploying both 32 bit and 64 bit COM DLLs
In some cases, such as shell extensions, you may need to deploy both 32 bit DLLs and 64 bit DLLs, so that 32 bit processes can load the 32 bit DLL, while 64 bit processes can load the 64 bit DLL.
You don’t need two different GUIDs. Both the DLLs can have the same GUIDs. The 32 bit DLL must be registered using 32 bit Regsvr32.exe. While the 64 bit DLL must be registered using 64 bit Regsvr32.exe. This will ensure that both the registration happen in their own separate areas of the registry.
You will find the Regsvr32.exe in following locations:
C:\Windows\System32\regsvr32.exe (64 bit)
C:\Windows\SysWow64\regsvr32.exe (32 bit)
To register successfully using regsvr32.exe, you will need to launch Command Prompt as an administrator. To do this, right click on ‘Command Prompt’ and choose ‘Run as Administrator’.
The registry in Win64 has different areas for storing 32 bit COM registrations.
To view the 64 bit Registry, run:
To view the 32 bit Registry, run:
We are using -m so that a separate instance of Registry Editor can be run while the 64 bit Registry Editor is running
Deploying both 32 bit and 64 bit hook DLLs
In case of system wide hook DLLs, you will need to have 2 DLLs (32 bit and 64 bit) and 2 EXEs (32 bit and 64 bit) that will actually hook the DLLs. So, at anytime you will have 2 EXEs running. One for each DLL.