Failed to grab execution mutex. System error 258.

The error in the title can happen during MSI installations, if the msiexec global mutex is not available.

I encountered it while developing a small script that would uninstall all existing JRE versions on the machine and install the latest one (using the msi package).

Apparently the JRE uninstall command spawns the Java Automatic Update (AU) uninstaller, but returns control immediately to the caller. Hence, if I perform a JRE uninstall and immediately start another installation, it would sometime fail with MSI error 258 since Windows Installer is still busy with the AU uninstall.

The best solution I found so far is as mentioned in this Stack Overflow thread. I wrote a small program based on that code, that waits until the mutex is available (or until a certain timeout). So my script now runs the JRE uninstall, then the ‘wait for mutex’ program, and only then it launches the JRE installer, and everyone’s happy 🙂

‘Revocation information not available’ warning when installing JRE 7u51

I have an InstallShield project which, among other things, installs JRE 7u51 by simply calling: jre-7u51-windows-i586.exe /s

When deploying this setup on a vCloud-based virtual machine, we receive the notorious ‘revocation information for the security certificate for this site is not available’.

The reason, as it turned out, is that the jre installer attempts to query a certain web site in order to validate the certificate revocation status of the Java Auto-Updated; and, since the requests comes from a vCloud machine, the web site tries to return the answer to the internal IP, while the server is only accessible through its external IP.

Since we don’t want the auto-update feature anyway (some of our customers are not even connected to the Internet), the solution was to disable auto-updating all together. This is achieved by installing jre with certain MSI parameters.

But here’s another caveat – the jre exe installer does not pass parameters to the MSI when using /v … hence, the solution must be to use the msi directly. Here is how to do it:

1. Run the usual jre installation. While running (or afterwards), open the following folder: %USERPROFILE%\AppData\LocalLow\Sun\Java

2. In that folder, copy the jre1.7.0_51.msi and Data1.cab to another location

3. Change your installation script to deploy jre using the command:

msiexec /i jre1.7.0.msi AUTOUPDATECHECK=0 IEXPLORER=1 JAVAUPDATE=0 JU=0 MOZILLA=1 /qn ALLUSERS=2

4. Test the installation. You should now have no auto-update, and no certificate revocation warning.

Mission accomplished!

Unicode files and InstallShield

I’ve prepared a little test – an InstallScript MSI project that executes the following code:

szFile = TempFolder ^ "web.config"; // A UTF-8 file
listID = ListCreate (STRINGLIST);
ListReadFromFile(listID,szFile);
ListWriteToFile(listID,szFile);
ListDestroy(listID);

Despite the claim that “if the file already exists and the pre-existing file is Unicode, it writes the file as Unicode”, the resulting file is actually ANSI, with two strange characters at the beginning of the file (I assume this is due to the Unicode BOM).

Turns out that InstallShield only supports the UCS-2/UTF-16 LE encoding (the native Windows Unicode implementation). Hence UTF-8 files are not supported.

Bottom line: when processing Unicode files using InstallScript, make sure they are properly encoded!

Use CtrlGetMultCurSel with Extended Selection List Box

The official InstallShield 2013 documentation states the following:

The CtrlGetMultCurSel function retrieves the currently selected lines from a multi-selection list box control, that is, a list box control with the LBS_MULTIPLESEL style. (This function does not support extended selection list box controls, that is, list box controls with the LBS_EXTENDEDSEL style.)

Turns out this is not entirely correct. If you set both list box styles (LBS_MULTIPLESEL and LBS_EXTENDEDSEL), then the list box has extended multi-selection style, but CtrlGetMultCurSel() works well with it.

Setup Launcher Unicode has stopped working

Recently we migrated one of our InstallScript MSI project to InstallShield 2013.
Everything went well, until our most recent build, which simply crashes mid-installation. The ‘Fault Module Name’ is ISSetup.dll, but that’s about all the comprehensive information I could get from the crash report.
After adding custom logging (essentially logging every line in our InstallScript code), the problem was found. It seems to be an InstallShield bug (confirmed also on InstallShield 2013 SP1).
Here is the code who caused the crash, and how I fixed it:

// This will cause a crash
FileCopy(szSourceDir ^ szFileName, szTargetDir);
// This will not cause a crash
FileCopy(szSourceDir ^ szFileName, szTargetDir ^ szFileName);

 

Inno setup – restore files on uninstall

Suppose you are using an Inno Setup project to replace existing files. When running the uninstaller it will delete the new files, instead of the expected behavior of restoring the previous ones.
Here is my implementation of a backup & restore mechanism:

1. For each file to be backed up, add a ‘Check’ parameter with the name of your backup function. This function will be called just before installing the file so we can use it to perform the backup.

2. Implement the backup function to perform the backup. Make sure to return True if everything’s OK and the file can be replaced.

3. Implement the restore function by copying all files from backup to the original location.

4. Call the restore function during uninstall (post-uninstall, after the new files have been removed).

Here is a sample Inno Setup script that implements this mechanism. In this example, the backup function supports backing up the entire folder structure, so restoring them to the original location is easy (using xcopy).

Continue reading

InstallShield Minor Upgrade Wows

So, I have this InstallScript MSI project, with some components, all of them using dynamic files.

The idea is that, for ‘full’ version, it will include all files of the software, and for minor upgrades/patches, it would only include the modified files.

(No, we can’t use static files, and we can’t use the MSI patch mechanism – this is a story for some other time.)

In order for this ‘partial’ upgrade to work, I’m building a Minor Upgrade (i.e. same product code as the ‘full’ version, and higher version number). I also set REINSTALLMODE=vamus, since most of the files are not versioned.

The installation runs, and apparently several files were not replaced. This is what I see in the MSI log:

“Modifying REINSTALLMODE property. Its current value is ‘vamus’. Its new value: ‘vomus’.”

The nerve! How dare you!

Trying to force ‘vamus’, by running ‘setup.exe REINSTALLMODE=vamus’, I get the following error:

Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.

I gave up and switched to Major upgrade.

Preventing msi package from rebooting the system

When running msiexec to install, update or remove a certain product, you may want to prevent it from rebooting the system, or even prompt the user to reboot the system (e.g. if it’s a part of a larger installation or some other scripted operation).

Before Windows Installer 3.0, the only way to do it was setting the Windows Installer REBOOT property like this:

msiexec /i MyPackage.msi REBOOT=ReallySuppress

In Windows Installer 3.0, Microsoft added several command line switches which makes it more readable. So now the command looks like this:

msiexec /i MyPackage.msi /norestart

Much clearer, isn’t it?