Menu

Fixing a corrupted Java install programmatically from C#

April 1, 2014 - Programming

When it comes to using different Programming languages, you should simply use whichever language is best at the goal you have in mind. As near as I can tell C# and .NET lack in terms of free reporting Software. Java has a number of options, the relevant one here being Jasper Reports.

While it is probably possible to convert the Java source of Jasper Reports to .NET and use it natively, that has it’s own share of issues. So Basically the program in question shells out to a Java Wrapper. All of the products are managed with an updater- including the Java version.

It turns out, however, that Java is rather easy to corrupt, especially when the updater decides to tinker with the innards by renaming files. Originally designed to protect the applications we are responsible for, the rename logic is designed to allow the updater to install programs even if they are being used- EXE Modules that are in use can be renamed without issue. This unfortunately carried over the Java installer.

Under normal circumstances this wouldn’t really hurt. You would expect the installer to simply install and install the new files. As fate would have it, However, the Java installer fails with a return code of 1603 if the installer finds certain registry keys present when run silently. Though I wonder why a silent installer would not fix a corrupted installation rather than basically complaining that the existing install is corrupted, I had to determine what was happening.

Using Process Monitor I was able to determine the keys the installer was so fond of.

Java Runtime Environment

this key is found as HKEY_LOCAL_MACHINE\Software\Javasoft\Java Runtime Environment. The subkeys of this key list installed Java versions. Within 64-bit C# applications you can change the Registry View to access the 32-bit registry. if your application is 32-bit, you can access the 64-bit registry in .NET 4 and later using:

.NET 3.5 and earlier will require you to use the API functions manually, At least partly. You can create a RegistryKey instance from a Registry Key Handle too.

The subkeys of the HKEY_LOCAL_MACHINE\Software\Javasoft\Java Runtime Environment key are versions. In my case I have 1.7 and 1.7.0_51. These keys each have their own set of values. In my case the important one was “RuntimeLib”. The RuntimeLib key points at the appropriate jvm.dll file. If that is missing- the Install is corrupted.

Thus my approach to repairing this section of the Java install keys so that the Java Installer will run silent again was:

  1. Open the Key.
  2. Go through all Subkeys.
  3. Read the RuntimeLib value. If it is missing, or if the filename specified does not exist, delete the Version key. Otherwise, move to the next Subkey.

This will successfully remove the keys for corrupted installations from the registry. However, this is not the only place the Java installer ends up looking.

The Java installer executable for Windows is a packaged MSI installer. The installation information is registered within “Software\classes\Installer\Products”. Of note is that you will want the “Default” registry View; on a 64-bit system you will want the actual 64-bit Registry. if you are a 32-bit process on a 64-bit system, you’ll still want the 64-bit registry, and of course on a 32-bit system you’ll get the 32-bit registry. You can use the Environment.Is64BitOperatingSystem property to determine if your code is running on a 64-bit Operating System and use the appropriate RegistryView Enumeration constant. Essentially as a 32-bit process running on x64 you need to still access the “real” registry key rather than being redirected to the Wow6432Node key.

This is the fun part. Now you need to find the appropriate Installer Key for the version of Java that you detected as corrupted, and delete it. To do this you must scan all the Registry Keys and find the one with a ProductName Value of Java X Update Y based on the version information you extracted previously, and delete it- 64-bit installations will have “(64-bit)” on their Product Name.

Once those keys are deleted the Java Installer should be able to run silently without issue.

Have something to say about this post? Comment!