Zeus
Zeus

Reputation: 1087

Compare paths in Inno Setup

Is there a built-in way to compare two strings representing paths in Inno Setup Pascal? If not with one function, then perhaps via some normalisation of the path.

Naively comparing strings is obviously not correct, even if we ignore case with SameText() (as per the Windows rules).

As a minimum, correct comparison must

Resolving absolute vs. relative paths is a bonus, but it requires specifying the current path. Perhaps CWD is OK, but I'm not sure Inno accepts relative installation paths anyway.

This must be a fairly common task for an installer, but I'm surprised not to find an easy yet correct solution...

Upvotes: 4

Views: 257

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202272

Combine ExpandFileName, AddBackslash and SameText:

function SamePath(P1, P2: string): Boolean;
begin
  P1 := AddBackslash(ExpandFileName(P1));
  P2 := AddBackslash(ExpandFileName(P2));
  Result := SameText(P1, P2);
end;

The ExpandFileName:

  • Converts / to \.
  • Normalizes a sequence of any slashes to one backslash (except for leading backslashes in UNC paths).
  • Resolves relative paths.

The AddBackslash takes care of ignoring the trailing separators.


Tests:

procedure TestSamePath(P: string);
begin
  if not SamePath(P, 'C:\my\path\MyProg.exe') then
    RaiseException('Test failed: ' + P);
end;

function InitializeSetup(): Boolean;
begin
  TestSamePath('C:\my\path\MyProg.exe');
  TestSamePath('C:\my\path\MYPROG.exe');
  TestSamePath('C:\my\path\\MyProg.exe');
  TestSamePath('C:/my/path/MyProg.exe');
  TestSamePath('C:\my/path//MyProg.exe');
  TestSamePath('C:\my\path\MyProg.exe\');
  TestSamePath('C:\my\..\my\path\MyProg.exe');

  SetCurrentDir('C:\');
  TestSamePath('\my\path\MyProg.exe');
  TestSamePath('my\path\MyProg.exe');

  SetCurrentDir('C:\my');
  TestSamePath('path\MyProg.exe');
  TestSamePath('.\path\MyProg.exe');
  Result := True;
end;

Upvotes: 3

Related Questions