JNH
JNH

Reputation: 517

Inno Setup - AfterInstall action executed multiple times

I have the following piece of code to run in my script:

procedure AddRulesToFirewall();
var
  ResultCode: Integer;
begin
  Exec('netsh.exe','advfirewall firewall add rule name="MyApplication" dir=in program="{app}\MyApplication.exe" security=notrequired action=allow protocol=tcp','',SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;

And I have the following AfterInstall action:

Source:{#OutputBinaries}\Company*.dll; DestDir: {app}; Components: binaries; AfterInstall: AddRulesToFirewall()

However the AfterInstall action gets executed many times, therefore I am assuming that it runs the AfterInstall action for each binary grouped under this command.

My question is, how should I change this so that the AddRulesToFirewall code is only run once after the binaries are installed?

I realise that I could list all the binaries individually in the files section and have the AfterInstall only on the last binary, but as there are a lot of binaries I would rather not use this approach.

Upvotes: 2

Views: 855

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202652

Why do you use the AfterInstall parameter? How does the firewall rule relate to the DLL files?

Use the CurStepChanged(ssPostInstall) instead:

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
  begin
    AddRulesToFirewall;
  end;
end;

Though, if you really need to use the AfterInstall for some reason, you can use CurrentFileName magic variable, if you know the last file matching the wildcard.

procedure AddRulesToFirewall();
var
  ResultCode: Integer;
begin
  if ExtractFileName(CurrentFileName) = 'CompanyLast.dll' then
  begin
    Exec(
      'netsh.exe',
      'advfirewall firewall add rule name="MyApplication" dir=in ' +
        'program="{app}\MyApplication.exe" security=notrequired action=allow protocol=tcp',
      '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
  end;
end;

Though this may be unreliable.


Another option is, if the wildcard entry is not the last one, to use the BeforeInstall parameter of the next entry.

Source: Company*.dll; DestDir: {app}
Source: AnotherFile.dat; DestDir: {app}; BeforeInstall: AddRulesToFirewall()

Upvotes: 3

Related Questions