Monthly Archives: July 2013

10 or so years ago I worked on a CD-ROM product which continues to sell from time to time. At the time, we used a product called PC-Install to make the installer; since then we’ve moved on to Inno Setup.

Unfortunately, although our software was 32-bit, the installer produced by PC-Install was 16-bit, and some flavours of recent versions of Windows no longer run 16-bit software. So although the application could run, there was no way for users to install it.

So I set about using Inno Setup to create an installer which would work against the existing stock of CD-ROMs (binning them and issuing a new version isn’t financially viable).

The basic idea was for the installer to detect the CD-ROM, copy the files across, and set up the icons. Obviously, I couldn’t rely on the D: drive always being the optical drive, so I’d need to detect it dynamically. This stackoverflow post links to the code I used and adapted (it doesn’t work out of the box). It implements a function to discover the optical drive letter, and then uses a scripted constant to invoke it for use as the file source.

So, I got the function working, and then used it in my Source line:

Source: "{code:GetCdromDrive}\*.*"; DestDir: "{app}"; Flags: recursesubdirs;

However, when compiling/running this, I got the error:

Unknown filename prefix "{code:"

suggesting one couldn’t use scripted constants in Source lines. After a bit of fruitless experimentation and googling though I returned to the original example code and spotted I’d missed one of the Flags: ‘external’. This turns out to be the key:

Source: "{code:GetCdromDrive}\*.*"; DestDir: "{app}"; Flags: recursesubdirs external;

Apparently the source directory is ordinarily determined at compile time, and the ‘external’ keyword defers it to run time. (This is hardly obvious from the documentation though.)

%d bloggers like this: