Refactor Application by Removing 32-bit Code

Project Description

We have a legacy C++ application for Windows, which at the moment supports both 32-bit and 64-bit Windows. We need to simplify the app and the update infrastructure that supports it by removing 32-bit components.

The project goal is to reduce complexity of the application, the installer, and the update system that builds installers for customers on demand. Also, removing 32-bit binaries from the installer should make it smaller.

Completion Notes

We are dealing with a legacy application, which, over the years of development, improvements, and maintenance, became quite complex and difficult to maintain. Customer is looking at removing no longer relevant (or at least not so much needed) 32-bit parts. The first thing we need to have is a plan, as there are many pieces involved here.

Project Plan

Let's see what we need. Our considerations are as follows.

The update infrastructure updates both 32-bit and 64-bit programs. Therefore, we have to change it in a way, that a new 64-bit only installer is not downloaded by 32-bit programs. We have to check the OS bitness before allowing a program to download a new copy. We have 2 options here apparently. One is to send "No updates available" message back to 32 bit programs. Another option is to prohibit updates with a more specific message, if possible. Ideally, we want to display a message like "Support for 32-bit program has ended." The problem is that currently deployed programs cannot detect such situation properly.

When we have the update system working only with 64-bit deployed programs, we can then refactor the installer. It needs to be changed in a couple of ways.

Once we do it, we will still be using the old code base for the application, and the old application build process.

Our project plan, therefore, looks like this:

  1. Modify the update infrastructure to prohibit updates to 32-bit programs.
  2. Modify the installer to prohibit installs on 32-bit and other unsupported systems.
  3. Update customer website to explain the changes.
  4. Simplify the patching mechanism in the update infrastructure to deal only with 64-bit components.
  5. Refactor the installer code without changing the application code. Upon completion of this item, we'll have a smaller installer for 64-bit only systems.
  6. Remove 32-bit target from the build. This will accelerate our "Build-All" process.
  7. Refactor the application code to remove 32-bit checks, and anything related. This will slightly reduce the overall complexity of the application.

If we execute our project plan from top to bottom, then at each step we still have a fully functional everything with a single exception that 32-systems are no longer supported.

Although the entire project looks a bit scary, we now have much smaller steps that we can do incrementally, while still having everything working.

Disabling 32-bit Updates

Let's see how we can disable 32-bit updates.

It turns out that we can add a relatively simple check for bitness of the product in a Java application that handles updates. We can do so because the application transmits the information about it in its request to the update server. So, all we have to do is to check it and abort processing if the app is not 64-bit.

The existing app update mechanism then will pop up a message to a user saying "Maintenance Period Expired", with a link to a change log page. We can also update this page accordingly saying that support for 32-bit apps has ended.

This accomplishes our step 1 of the project with relative ease. 64-bit applications continue to update as before, 32-bit apps cannot do so through the update server.

Modifying Installer

Now can now modify the installer. We can probably do it in a few steps.

Notice that the above requires us to adjust all localization files and rebuild the application.

By thins point our installer is still big in size and is not refactored, but denies installs on no longer supported operating systems.

Updating Website

In this step we update content on customer website and application change log to explain the changes.

We monitor the updates for a while to see how things are going on, and see the first problem. Some end users are confused by the "Maintenance Period Expired" message, specifically some subscription-based users, and also some users who at some point received a free copy of the application.

Unfortunately, the deployed application is not smart enough to display a detailed message from the server, without it being updated first. But since we already stopped updating it, we must stick to what it can do.

A workaround is to detect an unsupported 32-bit update request on the server, and tell it we have no updates for it.

Fixing Patching

Our update infrastructure contains a patching mechanism that patches both 32-bit and 64-bit files. Our next step is to eliminate patching of 32-bit files. This will help to avoid problems when the files are physically removed.

We have to modify the parameters to the patching system for all license types of the product.

After we do it, it turns out that the dynamic build process becomes broken, as the patching process also moved the file to a designated place for the installer script to pick up. As it is no longer there, the installer cannot build anything now. Let's try to fix the installer be removing the step that included the eliminated patched file.

It looks like the above step fixes the issue. The dynamic build system is functioning again, also it builds slightly smaller installer because we excluded one no longer needed component.

Refactoring Installer

Our next step is refactoring installer code. We have to remove all 32-bit files from getting into it. We also want to clean it up and organize better, so that the code is simpler and easier to maintain.

After this step is done, we have a smaller, leaner installer, which is better organized for future maintenance.

Removing 32-bit Targets

This step is relatively straightforward, as we remove Win32 Platform from the builds, by adjusting project properties. As a result, we have a reduced subset of targets to build, and the build process completes much faster.

Refactoring the Application

As the application is quite complex, we have to carefully review it and remove everything related to 32-bit platforms. For example, the sections that use conditional compilation depending whether preprocessor macro _M_IX86 is defined.

So, we do it and, at this point, our project is completed.

You can leave a comment on this project, or post a new project for consideration.