The Curious Case Of 64-bit MSI

Over the past couple of years, more and more companies have rolled out the 64-bit version of their respective products, including Office and Oracle. Office has both 32-bit and 64-bit versions of their new Office 2010 platform. Similarly, Oracle has also released the 64-bit version of their client drivers in addition to the already existing 32-bit versions.

For these 64-bit versions to work seamlessly, all the components that they depend on also has to be 64-bit. For example, Office 2010 64-bit version cannot access any add-ins or legacy COM components that are 32-bit. Similarly if there is a database connectivity to be made from Office 2010 64-bit, it requires the 64-bit version of the oracle drivers.

Recently I encountered a situation where I had to convert a 32-bit .net COM component to 64-bit to be accessed from 64-bit Office. The COM component was packaged as an MSI file which will be installed on the user machines. To me, converting this to 64-bit was a no-brainer.

  • Take the setup program used to create the MSI package
  • Change the Target Platform to 64-bit
  • Build the MSI
  • Deploy

And that is exactly what I did, job done in 20 minutes! But to my surprise, the Office 64-bit refused to recognize the installed COM component. What’s going on?

Digging deeper, I found that the component is getting registered in the SYSWOW64 section in the registry instead of the SYSTEM32 section. Now, if you are not familiar with the SYSWOW64, this is where Microsoft decided to put all 32-bit programs on a 64-bit machine (like Win 7) and SYSTEM32 is where all the 64-bit programs will reside (I know the naming is just confusing!).

I went on to reason that if the component is getting registered in the SYSWOW64, then somehow the installation process should be running as a 32-bit process. But I did change the Target Platform to 64-bit, didn’t I? I did!

target_platform_64bit

Browsing through a number of MSDN blogs and knowledge base articles with my new friend, BING, I found a blog post where it was explained that there is a small glitch with the setup program bundled with Visual Studio 2010 and there is an additional step that needs to be done to make the MSI truly 64-bit.

Visual Studio 2010 Setup Program

If the installation program includes custom actions, Visual Studio 2010, when creating the MSI, includes an additional DLL called InstallUtilLib.dll. When this DLL is included, the setup program includes this from the 32-bit area of the .net framework instead of the 64-bit Framework64 folder. When the MSI runs, it detects that there is a dependency that is not supported on 64-bit and runs the entire process as 32-bit.

Currently, nothing can be done directly from Visual Studio to correct this situation. The suggestion is to modify the MSI after it has been created.

Orca to the rescue

Orca is a program that is used to create or modify an MSI installable file. It is bundled along with the .net framework SDK, so if you have Visual Studio, it is likely that you already have it. I searched the term ‘orca’ in my program files and it threw up the Orca.msi, which then I installed.

What are we modifying? We are going to open the MSI that was created by Visual Studio in Orca, replace the InstallUtilLib.dll (32-bit) that was added by default with the 64-bit version of the same DLL.

First open the MSI in Orca.

orca_installutillib - Copy

The left hand side displays all the tables that are present in this MSI. Choose the ‘Binary’ table. On the right hand side, you will see the entry for ‘InstallUtil’.

Double click on the area where it says ‘[Binary Data]’. It will open a ‘Edit Binary Stream’ dialog as shown below. Make sure the ‘Read binary from filename’ option is selected.

orca_edit_binary_stream

Click on Browse.

Browse to %WINDIR%Microsoft.NETFramework64v2.0.50727

Select ‘InstallUtilLib.dll’.

Click on OK button.

Notice that the folder name says ‘Framework64’ (with a suffix ‘64’). The Framework folder (without the suffix ‘64’) is its 32-bit counterpart.

Save the MSI file.

Voila! With the 32-bit dependency removed from the MSI, the MSI now runs as a 64-bit process, registering the COM in the SYSTEM32 section and correctly so.

Problem solved!