'Validate a /DIR param and default {app} value

There is a way to validate the value passed by command line with /DIR= parameter? Something like this:

C:\>MySetup.exe /DIR="An\invalid\path\here"

By validate I mean: if the directory doesn't exist, I would like to use the default value of the constant {app}, considering that the software may already be installed (UserPreviousAppDir=yes).

I tried to validate the value passed by /DIR= with CurPageChanged() in [Code] section.

[Code]
procedure CurPageChanged(CurPageID: Integer);
var
  Dir, DirCmd: String;
begin
  if (CurPageID = wpSelectDir) then 
  begin
    // default directory 
    Dir := ExpandConstant('{app}'); // <- Error here
    // test /DIR parameter
    DirCmd := ExpandConstant('{param:DIR|0}');  
    if ( DirExists(DirCmd) ) then
      Dir := DirCmd;
    // set Select Destination Location page  
    WizardForm.DirEdit.Text := Dir;
  end;
end;

The problem I see is that before the Select Destination Location page the constant {app} has not been defined yet and WizardDirValue() has the same value passed by /DIR=. So I can check that the directory do or not exists, but I can't find a way to replace it with the default value of {app} if no /DIR= had been used.



Solution 1:[1]

There is a solution using AppId and InstallLocation for scripts with Uninstall configuration.

[Code]
function GetAppIdString(): String;
var
  S: String;
begin
  S := '{#SetupSetting("AppId")}';
  // ignore first { when AppId={{
  if ( (S[1] = '{') and (S[2] = '{') ) then
    S := Copy(S, 2, Length(S) - 1);
  Result := S;
end;

function GetRegistryInstallLocation(): String;
var
  RegKey: String;
  Path: String;
begin
  // InnoSetup uninstall registry key
  RegKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + GetAppIdString() + '_is1\';
  // try LocalMachine and CurrentUser
  if not RegQueryStringValue(HKEY_LOCAL_MACHINE, RegKey, 'InstallLocation', Path) then
  if not RegQueryStringValue(HKEY_CURRENT_USER , RegKey, 'InstallLocation', Path) then
    Path := '';
  // result  
  Result := Path;
end;

procedure InitializeWizard();
var
  Dir, DirCmd: String;
begin
  // default directory 
  //Dir := ExpandConstant('{app}'); // <- Error here
  Dir := GetRegistryInstallLocation();
  // test /DIR parameter
  DirCmd := ExpandConstant('{param:DIR|0}');  
  if ( DirExists(DirCmd) ) then
    Dir := DirCmd;
  // set Select Destination Location page  
  WizardForm.DirEdit.Text := Dir;
end;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martin Prikryl