4
votes

I've recently started using Inno Setup to try and create a simple .exe installer for a game modification.

I've got the installer working fine for the most part, but it's a little basic at the moment. What I would really like the installer to do is to automatically find the install directory of the game the mod is designed for (Dawn of War - Dark Crusade) so the user doesn't need to browse to it manually.

I've read that Inno installer can set a DefaultDir as per a registry entry. However, while the 'target' game does create a registry entry containing its install directory, the game can be purchased either digitally (through Steam) or physically, and it creates different registry entries depending on the format it's bought in. My mod works with either format, but I don't know how to set the DefaultDir if there's more than one possible registry key format.

Is there some sort of 'wilcard' function that will return the game's install directory from its registry entry without my having to enter the exact, full registry key value (ie, some sort of registry wildcard)? Or of searching for the two possible values it could have, then defaulting to {src} if it doesn't find either?

2

2 Answers

4
votes

You can assign value of a DefaultDirName directive through the [Code] section. For instance, the following pseudo-script shows how to query two string values in registry and return the first found to the DefaultDirName directive. If none of the queried registry values is found, a default constant value is returned:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={code:GetDirName}

[Code]
function GetDirName(Value: string): string;
var          
  InstallPath: string;
begin
  // initialize default path, which will be returned when the following registry
  // key queries fail due to missing keys or for some different reason
  Result := '{pf}\Default Dir Name';
  // query the first registry value; if this succeeds, return the obtained value
  if RegQueryStringValue(HKLM, 'Software\Vendor\Application', 'First Key', InstallPath) then
    Result := InstallPath
  // otherwise the first registry key query failed, so...
  else
  // query the second registry value; if it succeeds, return the obtained value
  if RegQueryStringValue(HKLM, 'Software\Vendor\Application', 'Second Key', InstallPath) then
    Result := InstallPath;
end;
4
votes

In addition to using [Code] as answered elsewhere, you can also nest registry constants:

DefaultDirName={reg:HKLM,Software\Vendor1\Application,InstallPath|{reg:HKLM,Software\Vendor2\Application,InstallPath|{pf}\DefaultInstallPath}}

This will use Vendor1's path if it exists; failing that it will try Vendor2's path, and only if it cannot find either of those will it fall back to some default value.